mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
Merge branch '756-group-visibility' into 'master'
Add third group visibility state This branch adds a third group visibility state: each group is either invisible, visible, or shared with respect to each contact. Invisible means that the contact doesn't see any sign that we subscribe to the group. Visible means that the contact can send us messages in the group, but we won't send the contact messages in the group. Shared means that the contact can send us messages in the group and we'll send the contact any shared messages in the group. This is a preparatory step for #756. I'll put up another MR with the changes that close that ticket. See merge request !410
This commit is contained in:
@@ -66,6 +66,7 @@ import static org.briarproject.api.privategroup.Visibility.REVEALED_BY_CONTACT;
|
||||
import static org.briarproject.api.privategroup.Visibility.REVEALED_BY_US;
|
||||
import static org.briarproject.api.privategroup.Visibility.VISIBLE;
|
||||
import static org.briarproject.api.privategroup.invitation.GroupInvitationManager.CLIENT_ID;
|
||||
import static org.briarproject.api.sync.Group.Visibility.SHARED;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.PENDING;
|
||||
@@ -348,9 +349,9 @@ public class PrivateGroupManagerTest extends BriarIntegrationTest {
|
||||
assertEquals(joinMsg0.getMessage().getId(),
|
||||
groupManager0.getPreviousMsgId(groupId0));
|
||||
|
||||
// make group visible to 1
|
||||
// share the group with 1
|
||||
Transaction txn0 = db0.startTransaction(false);
|
||||
db0.setVisibleToContact(txn0, contactId1, privateGroup0.getId(), true);
|
||||
db0.setGroupVisibility(txn0, contactId1, privateGroup0.getId(), SHARED);
|
||||
db0.commitTransaction(txn0);
|
||||
db0.endTransaction(txn0);
|
||||
|
||||
@@ -371,9 +372,10 @@ public class PrivateGroupManagerTest extends BriarIntegrationTest {
|
||||
assertEquals(joinMsg1.getMessage().getId(),
|
||||
groupManager1.getPreviousMsgId(groupId0));
|
||||
|
||||
// make group visible to 0
|
||||
// share the group with 0
|
||||
Transaction txn1 = db1.startTransaction(false);
|
||||
db1.setVisibleToContact(txn1, contactId01, privateGroup0.getId(), true);
|
||||
db1.setGroupVisibility(txn1, contactId01, privateGroup0.getId(),
|
||||
SHARED);
|
||||
db1.commitTransaction(txn1);
|
||||
db1.endTransaction(txn1);
|
||||
|
||||
@@ -415,9 +417,9 @@ public class PrivateGroupManagerTest extends BriarIntegrationTest {
|
||||
assertEquals(joinMsg0.getMessage().getId(),
|
||||
groupManager0.getPreviousMsgId(groupId0));
|
||||
|
||||
// make group visible to 1
|
||||
// share the group with 1
|
||||
Transaction txn0 = db0.startTransaction(false);
|
||||
db0.setVisibleToContact(txn0, contactId1, privateGroup0.getId(), true);
|
||||
db0.setGroupVisibility(txn0, contactId1, privateGroup0.getId(), SHARED);
|
||||
db0.commitTransaction(txn0);
|
||||
db0.endTransaction(txn0);
|
||||
|
||||
@@ -438,9 +440,9 @@ public class PrivateGroupManagerTest extends BriarIntegrationTest {
|
||||
assertEquals(joinMsg1.getMessage().getId(),
|
||||
groupManager1.getPreviousMsgId(groupId0));
|
||||
|
||||
// make group visible to 0
|
||||
// share the group with 0
|
||||
Transaction txn1 = db1.startTransaction(false);
|
||||
db1.setVisibleToContact(txn1, contactId01, privateGroup0.getId(), true);
|
||||
db1.setGroupVisibility(txn1, contactId01, privateGroup0.getId(), SHARED);
|
||||
db1.commitTransaction(txn1);
|
||||
db1.endTransaction(txn1);
|
||||
|
||||
@@ -518,9 +520,9 @@ public class PrivateGroupManagerTest extends BriarIntegrationTest {
|
||||
public void testRevealingRelationships() throws Exception {
|
||||
defaultInit();
|
||||
|
||||
// make group visible to 2
|
||||
// share the group with 2
|
||||
Transaction txn0 = db0.startTransaction(false);
|
||||
db0.setVisibleToContact(txn0, contactId2, privateGroup0.getId(), true);
|
||||
db0.setGroupVisibility(txn0, contactId2, privateGroup0.getId(), SHARED);
|
||||
db0.commitTransaction(txn0);
|
||||
db0.endTransaction(txn0);
|
||||
|
||||
@@ -540,8 +542,9 @@ public class PrivateGroupManagerTest extends BriarIntegrationTest {
|
||||
Transaction txn2 = db2.startTransaction(false);
|
||||
groupManager2.addPrivateGroup(txn2, privateGroup0, joinMsg2, false);
|
||||
|
||||
// make group visible to 0
|
||||
db2.setVisibleToContact(txn2, contactId01, privateGroup0.getId(), true);
|
||||
// share the group with 0
|
||||
db2.setGroupVisibility(txn2, contactId01, privateGroup0.getId(),
|
||||
SHARED);
|
||||
db2.commitTransaction(txn2);
|
||||
db2.endTransaction(txn2);
|
||||
|
||||
@@ -741,9 +744,9 @@ public class PrivateGroupManagerTest extends BriarIntegrationTest {
|
||||
assertEquals(joinMsg0.getMessage().getId(),
|
||||
groupManager0.getPreviousMsgId(groupId0));
|
||||
|
||||
// make group visible to 1
|
||||
// share the group with 1
|
||||
Transaction txn0 = db0.startTransaction(false);
|
||||
db0.setVisibleToContact(txn0, contactId1, privateGroup0.getId(), true);
|
||||
db0.setGroupVisibility(txn0, contactId1, privateGroup0.getId(), SHARED);
|
||||
db0.commitTransaction(txn0);
|
||||
db0.endTransaction(txn0);
|
||||
|
||||
@@ -762,9 +765,10 @@ public class PrivateGroupManagerTest extends BriarIntegrationTest {
|
||||
inviteTime, creatorSignature);
|
||||
groupManager1.addPrivateGroup(privateGroup0, joinMsg1, false);
|
||||
|
||||
// make group visible to 0
|
||||
// share the group with 0
|
||||
Transaction txn1 = db1.startTransaction(false);
|
||||
db1.setVisibleToContact(txn1, contactId01, privateGroup0.getId(), true);
|
||||
db1.setGroupVisibility(txn1, contactId01, privateGroup0.getId(),
|
||||
SHARED);
|
||||
db1.commitTransaction(txn1);
|
||||
db1.endTransaction(txn1);
|
||||
assertEquals(joinMsg1.getMessage().getId(),
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.briarproject.api.settings.Settings;
|
||||
import org.briarproject.api.sync.Ack;
|
||||
import org.briarproject.api.sync.ClientId;
|
||||
import org.briarproject.api.sync.Group;
|
||||
import org.briarproject.api.sync.Group.Visibility;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
import org.briarproject.api.sync.Message;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
@@ -232,6 +233,15 @@ public interface DatabaseComponent {
|
||||
*/
|
||||
Collection<Group> getGroups(Transaction txn, ClientId c) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the given group's visibility to the given contact, or
|
||||
* {@link Visibility INVISIBLE} if the group is not in the database.
|
||||
* <p/>
|
||||
* Read-only.
|
||||
*/
|
||||
Visibility getGroupVisibility(Transaction txn, ContactId c, GroupId g)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the local pseudonym with the given ID.
|
||||
* <p/>
|
||||
@@ -388,14 +398,6 @@ public interface DatabaseComponent {
|
||||
void incrementStreamCounter(Transaction txn, ContactId c, TransportId t,
|
||||
long rotationPeriod) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns true if the given group is visible to the given contact.
|
||||
* <p/>
|
||||
* Read-only.
|
||||
*/
|
||||
boolean isVisibleToContact(Transaction txn, ContactId c, GroupId g)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Merges the given metadata with the existing metadata for the given
|
||||
* group.
|
||||
@@ -470,6 +472,12 @@ public interface DatabaseComponent {
|
||||
void setContactActive(Transaction txn, ContactId c, boolean active)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Sets the given group's visibility to the given contact.
|
||||
*/
|
||||
void setGroupVisibility(Transaction txn, ContactId c, GroupId g,
|
||||
Visibility v) throws DbException;
|
||||
|
||||
/**
|
||||
* Marks the given message as shared.
|
||||
*/
|
||||
@@ -494,12 +502,6 @@ public interface DatabaseComponent {
|
||||
void setReorderingWindow(Transaction txn, ContactId c, TransportId t,
|
||||
long rotationPeriod, long base, byte[] bitmap) throws DbException;
|
||||
|
||||
/**
|
||||
* Makes a group visible or invisible to a contact.
|
||||
*/
|
||||
void setVisibleToContact(Transaction txn, ContactId c, GroupId g,
|
||||
boolean visible) throws DbException;
|
||||
|
||||
/**
|
||||
* Stores the given transport keys, deleting any keys they have replaced.
|
||||
*/
|
||||
|
||||
@@ -2,6 +2,12 @@ package org.briarproject.api.sync;
|
||||
|
||||
public class Group {
|
||||
|
||||
public enum Visibility {
|
||||
INVISIBLE, // The group is not visible
|
||||
VISIBLE, // The group is visible but messages are not shared
|
||||
SHARED // The group is visible and messages are shared
|
||||
}
|
||||
|
||||
private final GroupId id;
|
||||
private final ClientId clientId;
|
||||
private final byte[] descriptor;
|
||||
|
||||
@@ -12,7 +12,6 @@ import org.briarproject.api.blogs.MessageType;
|
||||
import org.briarproject.api.clients.Client;
|
||||
import org.briarproject.api.clients.ClientHelper;
|
||||
import org.briarproject.api.contact.Contact;
|
||||
import org.briarproject.api.contact.ContactId;
|
||||
import org.briarproject.api.contact.ContactManager;
|
||||
import org.briarproject.api.data.BdfDictionary;
|
||||
import org.briarproject.api.data.BdfEntry;
|
||||
@@ -68,6 +67,7 @@ import static org.briarproject.api.blogs.MessageType.WRAPPED_COMMENT;
|
||||
import static org.briarproject.api.blogs.MessageType.WRAPPED_POST;
|
||||
import static org.briarproject.api.contact.ContactManager.AddContactHook;
|
||||
import static org.briarproject.api.contact.ContactManager.RemoveContactHook;
|
||||
import static org.briarproject.api.sync.Group.Visibility.SHARED;
|
||||
import static org.briarproject.blogs.BlogPostValidator.authorToBdfDictionary;
|
||||
|
||||
@NotNullByDefault
|
||||
@@ -96,35 +96,24 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
|
||||
|
||||
@Override
|
||||
public void createLocalState(Transaction txn) throws DbException {
|
||||
// Ensure that the local identity has its own personal blog
|
||||
LocalAuthor la = identityManager.getLocalAuthor(txn);
|
||||
Blog b = blogFactory.createBlog(la);
|
||||
Group g = b.getGroup();
|
||||
if (!db.containsGroup(txn, g.getId())) {
|
||||
db.addGroup(txn, g);
|
||||
for (ContactId c : db.getContacts(txn, la.getId())) {
|
||||
db.setVisibleToContact(txn, c, g.getId(), true);
|
||||
}
|
||||
}
|
||||
// Ensure that we have the personal blogs of all pre-existing contacts
|
||||
// Create our personal blog if necessary
|
||||
LocalAuthor a = identityManager.getLocalAuthor(txn);
|
||||
Blog b = blogFactory.createBlog(a);
|
||||
db.addGroup(txn, b.getGroup());
|
||||
// Ensure that we have the personal blogs of all contacts
|
||||
for (Contact c : db.getContacts(txn)) addingContact(txn, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addingContact(Transaction txn, Contact c) throws DbException {
|
||||
// get personal blog of the contact
|
||||
// Add the personal blog of the contact and share it with the contact
|
||||
Blog b = blogFactory.createBlog(c.getAuthor());
|
||||
Group g = b.getGroup();
|
||||
if (!db.containsGroup(txn, g.getId())) {
|
||||
// add the personal blog of the contact
|
||||
db.addGroup(txn, g);
|
||||
db.setVisibleToContact(txn, c.getId(), g.getId(), true);
|
||||
|
||||
// share our personal blog with the new contact
|
||||
LocalAuthor a = db.getLocalAuthor(txn, c.getLocalAuthorId());
|
||||
Blog b2 = blogFactory.createBlog(a);
|
||||
db.setVisibleToContact(txn, c.getId(), b2.getId(), true);
|
||||
}
|
||||
db.addGroup(txn, b.getGroup());
|
||||
db.setGroupVisibility(txn, c.getId(), b.getId(), SHARED);
|
||||
// Share our personal blog with the contact
|
||||
LocalAuthor a = identityManager.getLocalAuthor(txn);
|
||||
Blog b2 = blogFactory.createBlog(a);
|
||||
db.setGroupVisibility(txn, c.getId(), b2.getId(), SHARED);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.briarproject.api.identity.LocalAuthor;
|
||||
import org.briarproject.api.settings.Settings;
|
||||
import org.briarproject.api.sync.ClientId;
|
||||
import org.briarproject.api.sync.Group;
|
||||
import org.briarproject.api.sync.Group.Visibility;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
import org.briarproject.api.sync.Message;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
@@ -72,6 +73,13 @@ interface Database<T> {
|
||||
*/
|
||||
void addGroup(T txn, Group g) throws DbException;
|
||||
|
||||
/**
|
||||
* Sets the given group's visibility to the given contact to either
|
||||
* {@link Visibility VISIBLE} or {@link Visibility SHARED}.
|
||||
*/
|
||||
void addGroupVisibility(T txn, ContactId c, GroupId g, boolean shared)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Stores a local pseudonym.
|
||||
*/
|
||||
@@ -98,7 +106,7 @@ interface Database<T> {
|
||||
* Initialises the status of the given message with respect to the given
|
||||
* contact.
|
||||
*
|
||||
* @param ack whether the message needs to be acknowledged.
|
||||
* @param ack whether the message needs to be acknowledged.
|
||||
* @param seen whether the contact has seen the message.
|
||||
*/
|
||||
void addStatus(T txn, ContactId c, MessageId m, boolean ack, boolean seen)
|
||||
@@ -116,11 +124,6 @@ interface Database<T> {
|
||||
void addTransportKeys(T txn, ContactId c, TransportKeys k)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Makes a group visible to the given contact.
|
||||
*/
|
||||
void addVisibility(T txn, ContactId c, GroupId g) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns true if the database contains the given contact for the given
|
||||
* local pseudonym.
|
||||
@@ -166,17 +169,9 @@ interface Database<T> {
|
||||
boolean containsTransport(T txn, TransportId t) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns true if the database contains the given group and the group is
|
||||
* visible to the given contact.
|
||||
* <p/>
|
||||
* Read-only.
|
||||
*/
|
||||
boolean containsVisibleGroup(T txn, ContactId c, GroupId g)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns true if the database contains the given message and the message
|
||||
* is visible to the given contact.
|
||||
* Returns true if the database contains the given message, the message is
|
||||
* shared, and the visibility of the message's group to the given contact
|
||||
* is either {@link Visibility VISIBLE} or {@link Visibility SHARED}.
|
||||
* <p/>
|
||||
* Read-only.
|
||||
*/
|
||||
@@ -267,6 +262,24 @@ interface Database<T> {
|
||||
*/
|
||||
Collection<Group> getGroups(T txn, ClientId c) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the given group's visibility to the given contact, or
|
||||
* {@link Visibility INVISIBLE} if the group is not in the database.
|
||||
* <p/>
|
||||
* Read-only.
|
||||
*/
|
||||
Visibility getGroupVisibility(T txn, ContactId c, GroupId g)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the IDs of all contacts to which the given group's visibility is
|
||||
* either {@link Visibility VISIBLE} or {@link Visibility SHARED}.
|
||||
* <p/>
|
||||
* Read-only.
|
||||
*/
|
||||
Collection<ContactId> getGroupVisibility(T txn, GroupId g)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the local pseudonym with the given ID.
|
||||
* <p/>
|
||||
@@ -477,13 +490,6 @@ interface Database<T> {
|
||||
Map<ContactId, TransportKeys> getTransportKeys(T txn, TransportId t)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the IDs of all contacts to which the given group is visible.
|
||||
* <p/>
|
||||
* Read-only.
|
||||
*/
|
||||
Collection<ContactId> getVisibility(T txn, GroupId g) throws DbException;
|
||||
|
||||
/**
|
||||
* Increments the outgoing stream counter for the given contact and
|
||||
* transport in the given rotation period.
|
||||
@@ -550,6 +556,13 @@ interface Database<T> {
|
||||
*/
|
||||
void removeGroup(T txn, GroupId g) throws DbException;
|
||||
|
||||
/**
|
||||
* Sets the given group's visibility to the given contact to
|
||||
* {@link Visibility INVISIBLE}.
|
||||
*/
|
||||
void removeGroupVisibility(T txn, ContactId c, GroupId g)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Removes a local pseudonym (and all associated state) from the database.
|
||||
*/
|
||||
@@ -585,11 +598,6 @@ interface Database<T> {
|
||||
*/
|
||||
void removeTransport(T txn, TransportId t) throws DbException;
|
||||
|
||||
/**
|
||||
* Makes a group invisible to the given contact.
|
||||
*/
|
||||
void removeVisibility(T txn, ContactId c, GroupId g) throws DbException;
|
||||
|
||||
/**
|
||||
* Resets the transmission count and expiry time of the given message with
|
||||
* respect to the given contact.
|
||||
@@ -607,6 +615,13 @@ interface Database<T> {
|
||||
void setContactActive(T txn, ContactId c, boolean active)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Sets the given group's visibility to the given contact to either
|
||||
* {@link Visibility VISIBLE} or {@link Visibility SHARED}.
|
||||
*/
|
||||
void setGroupVisibility(T txn, ContactId c, GroupId g, boolean shared)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Marks the given message as shared.
|
||||
*/
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.briarproject.api.settings.Settings;
|
||||
import org.briarproject.api.sync.Ack;
|
||||
import org.briarproject.api.sync.ClientId;
|
||||
import org.briarproject.api.sync.Group;
|
||||
import org.briarproject.api.sync.Group.Visibility;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
import org.briarproject.api.sync.Message;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
@@ -66,6 +67,8 @@ import java.util.logging.Logger;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.api.sync.Group.Visibility.INVISIBLE;
|
||||
import static org.briarproject.api.sync.Group.Visibility.SHARED;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.UNKNOWN;
|
||||
import static org.briarproject.db.DatabaseConstants.MAX_OFFERED_MESSAGES;
|
||||
@@ -97,6 +100,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
@Override
|
||||
public boolean open() throws DbException {
|
||||
Runnable shutdownHook = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
close();
|
||||
@@ -223,7 +227,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
private void addMessage(T txn, Message m, State state, boolean shared,
|
||||
@Nullable ContactId sender) throws DbException {
|
||||
db.addMessage(txn, m, state, shared);
|
||||
for (ContactId c : db.getVisibility(txn, m.getGroupId())) {
|
||||
for (ContactId c : db.getGroupVisibility(txn, m.getGroupId())) {
|
||||
boolean offered = db.removeOfferedMessage(txn, c, m.getId());
|
||||
boolean seen = offered || c.equals(sender);
|
||||
db.addStatus(txn, c, m.getId(), seen, seen);
|
||||
@@ -441,6 +445,15 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
return db.getGroups(txn, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Visibility getGroupVisibility(Transaction transaction, ContactId c,
|
||||
GroupId g) throws DbException {
|
||||
T txn = unbox(transaction);
|
||||
if (!db.containsContact(txn, c))
|
||||
throw new NoSuchContactException();
|
||||
return db.getGroupVisibility(txn, c, g);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalAuthor getLocalAuthor(Transaction transaction, AuthorId a)
|
||||
throws DbException {
|
||||
@@ -602,17 +615,6 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
db.incrementStreamCounter(txn, c, t, rotationPeriod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisibleToContact(Transaction transaction, ContactId c,
|
||||
GroupId g) throws DbException {
|
||||
T txn = unbox(transaction);
|
||||
if (!db.containsContact(txn, c))
|
||||
throw new NoSuchContactException();
|
||||
if (!db.containsGroup(txn, g))
|
||||
throw new NoSuchGroupException();
|
||||
return db.containsVisibleGroup(txn, c, g);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mergeGroupMetadata(Transaction transaction, GroupId g,
|
||||
Metadata meta) throws DbException {
|
||||
@@ -672,7 +674,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
T txn = unbox(transaction);
|
||||
if (!db.containsContact(txn, c))
|
||||
throw new NoSuchContactException();
|
||||
if (db.containsVisibleGroup(txn, c, m.getGroupId())) {
|
||||
if (db.getGroupVisibility(txn, c, m.getGroupId()) != INVISIBLE) {
|
||||
if (db.containsMessage(txn, m.getId())) {
|
||||
db.raiseSeenFlag(txn, c, m.getId());
|
||||
db.raiseAckFlag(txn, c, m.getId());
|
||||
@@ -745,7 +747,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
GroupId id = g.getId();
|
||||
if (!db.containsGroup(txn, id))
|
||||
throw new NoSuchGroupException();
|
||||
Collection<ContactId> affected = db.getVisibility(txn, id);
|
||||
Collection<ContactId> affected = db.getGroupVisibility(txn, id);
|
||||
db.removeGroup(txn, id);
|
||||
transaction.attach(new GroupRemovedEvent(g));
|
||||
transaction.attach(new GroupVisibilityUpdatedEvent(affected));
|
||||
@@ -794,6 +796,34 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
transaction.attach(new ContactStatusChangedEvent(c, active));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGroupVisibility(Transaction transaction, ContactId c,
|
||||
GroupId g, Visibility v) throws DbException {
|
||||
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
||||
T txn = unbox(transaction);
|
||||
if (!db.containsContact(txn, c))
|
||||
throw new NoSuchContactException();
|
||||
if (!db.containsGroup(txn, g))
|
||||
throw new NoSuchGroupException();
|
||||
Visibility old = db.getGroupVisibility(txn, c, g);
|
||||
if (old == v) return;
|
||||
if (old == INVISIBLE) {
|
||||
db.addGroupVisibility(txn, c, g, v == SHARED);
|
||||
for (MessageId m : db.getMessageIds(txn, g)) {
|
||||
boolean seen = db.removeOfferedMessage(txn, c, m);
|
||||
db.addStatus(txn, c, m, seen, seen);
|
||||
}
|
||||
} else if (v == INVISIBLE) {
|
||||
db.removeGroupVisibility(txn, c, g);
|
||||
for (MessageId m : db.getMessageIds(txn, g))
|
||||
db.removeStatus(txn, c, m);
|
||||
} else {
|
||||
db.setGroupVisibility(txn, c, g, v == SHARED);
|
||||
}
|
||||
List<ContactId> affected = Collections.singletonList(c);
|
||||
transaction.attach(new GroupVisibilityUpdatedEvent(affected));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMessageShared(Transaction transaction, MessageId m)
|
||||
throws DbException {
|
||||
@@ -845,33 +875,6 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
db.setReorderingWindow(txn, c, t, rotationPeriod, base, bitmap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisibleToContact(Transaction transaction, ContactId c,
|
||||
GroupId g, boolean visible) throws DbException {
|
||||
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
||||
T txn = unbox(transaction);
|
||||
if (!db.containsContact(txn, c))
|
||||
throw new NoSuchContactException();
|
||||
if (!db.containsGroup(txn, g))
|
||||
throw new NoSuchGroupException();
|
||||
boolean wasVisible = db.containsVisibleGroup(txn, c, g);
|
||||
if (visible && !wasVisible) {
|
||||
db.addVisibility(txn, c, g);
|
||||
for (MessageId m : db.getMessageIds(txn, g)) {
|
||||
boolean seen = db.removeOfferedMessage(txn, c, m);
|
||||
db.addStatus(txn, c, m, seen, seen);
|
||||
}
|
||||
} else if (!visible && wasVisible) {
|
||||
db.removeVisibility(txn, c, g);
|
||||
for (MessageId m : db.getMessageIds(txn, g))
|
||||
db.removeStatus(txn, c, m);
|
||||
}
|
||||
if (visible != wasVisible) {
|
||||
List<ContactId> affected = Collections.singletonList(c);
|
||||
transaction.attach(new GroupVisibilityUpdatedEvent(affected));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTransportKeys(Transaction transaction,
|
||||
Map<ContactId, TransportKeys> keys) throws DbException {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -73,6 +73,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ABORT
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ACK;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUEST;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPONSE;
|
||||
import static org.briarproject.api.sync.Group.Visibility.SHARED;
|
||||
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
|
||||
|
||||
@NotNullByDefault
|
||||
@@ -116,7 +117,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
|
||||
if (db.containsGroup(txn, g.getId())) return;
|
||||
// Store the group and share it with the contact
|
||||
db.addGroup(txn, g);
|
||||
db.setVisibleToContact(txn, c.getId(), g.getId(), true);
|
||||
db.setGroupVisibility(txn, c.getId(), g.getId(), SHARED);
|
||||
// Attach the contact ID to the group
|
||||
BdfDictionary gm = new BdfDictionary();
|
||||
gm.put(CONTACT, c.getId().getInt());
|
||||
|
||||
@@ -33,6 +33,7 @@ import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.api.sync.Group.Visibility.SHARED;
|
||||
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
|
||||
|
||||
@NotNullByDefault
|
||||
@@ -64,7 +65,7 @@ class MessagingManagerImpl extends ConversationClientImpl
|
||||
if (db.containsGroup(txn, g.getId())) return;
|
||||
// Store the group and share it with the contact
|
||||
db.addGroup(txn, g);
|
||||
db.setVisibleToContact(txn, c.getId(), g.getId(), true);
|
||||
db.setGroupVisibility(txn, c.getId(), g.getId(), SHARED);
|
||||
// Attach the contact ID to the group
|
||||
BdfDictionary d = new BdfDictionary();
|
||||
d.put("contactId", c.getId().getInt());
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.briarproject.api.privategroup.PrivateGroup;
|
||||
import org.briarproject.api.privategroup.PrivateGroupFactory;
|
||||
import org.briarproject.api.privategroup.PrivateGroupManager;
|
||||
import org.briarproject.api.sync.Group;
|
||||
import org.briarproject.api.sync.Group.Visibility;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
import org.briarproject.api.sync.Message;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
@@ -90,11 +91,10 @@ abstract class AbstractProtocolEngine<S extends Session>
|
||||
return dependency.equals(expected);
|
||||
}
|
||||
|
||||
void syncPrivateGroupWithContact(Transaction txn, S session, boolean sync)
|
||||
void setPrivateGroupVisibility(Transaction txn, S session, Visibility v)
|
||||
throws DbException, FormatException {
|
||||
ContactId contactId = getContactId(txn, session.getContactGroupId());
|
||||
db.setVisibleToContact(txn, contactId, session.getPrivateGroupId(),
|
||||
sync);
|
||||
db.setGroupVisibility(txn, contactId, session.getPrivateGroupId(), v);
|
||||
}
|
||||
|
||||
Message sendInviteMessage(Transaction txn, S session,
|
||||
|
||||
@@ -22,6 +22,8 @@ import org.briarproject.api.system.Clock;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import static org.briarproject.api.sync.Group.Visibility.INVISIBLE;
|
||||
import static org.briarproject.api.sync.Group.Visibility.SHARED;
|
||||
import static org.briarproject.privategroup.invitation.CreatorState.DISSOLVED;
|
||||
import static org.briarproject.privategroup.invitation.CreatorState.ERROR;
|
||||
import static org.briarproject.privategroup.invitation.CreatorState.INVITED;
|
||||
@@ -158,8 +160,8 @@ class CreatorProtocolEngine extends AbstractProtocolEngine<CreatorSession> {
|
||||
private CreatorSession onLocalLeave(Transaction txn, CreatorSession s)
|
||||
throws DbException {
|
||||
try {
|
||||
// Stop syncing the private group with the contact
|
||||
syncPrivateGroupWithContact(txn, s, false);
|
||||
// Make the private group invisible to the contact
|
||||
setPrivateGroupVisibility(txn, s, INVISIBLE);
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e); // Invalid group metadata
|
||||
}
|
||||
@@ -183,8 +185,8 @@ class CreatorProtocolEngine extends AbstractProtocolEngine<CreatorSession> {
|
||||
// Track the message
|
||||
messageTracker.trackMessage(txn, m.getContactGroupId(),
|
||||
m.getTimestamp(), false);
|
||||
// Start syncing the private group with the contact
|
||||
syncPrivateGroupWithContact(txn, s, true);
|
||||
// Share the private group with the contact
|
||||
setPrivateGroupVisibility(txn, s, SHARED);
|
||||
// Broadcast an event
|
||||
ContactId contactId = getContactId(txn, m.getContactGroupId());
|
||||
txn.attach(new GroupInvitationResponseReceivedEvent(contactId,
|
||||
@@ -224,8 +226,8 @@ class CreatorProtocolEngine extends AbstractProtocolEngine<CreatorSession> {
|
||||
// The dependency, if any, must be the last remote message
|
||||
if (!isValidDependency(s, m.getPreviousMessageId()))
|
||||
return abort(txn, s);
|
||||
// Stop syncing the private group with the contact
|
||||
syncPrivateGroupWithContact(txn, s, false);
|
||||
// Make the private group invisible to the contact
|
||||
setPrivateGroupVisibility(txn, s, INVISIBLE);
|
||||
// Move to the INVITEE_LEFT state
|
||||
return new CreatorSession(s.getContactGroupId(), s.getPrivateGroupId(),
|
||||
s.getLastLocalMessageId(), m.getId(), s.getLocalTimestamp(),
|
||||
@@ -236,9 +238,9 @@ class CreatorProtocolEngine extends AbstractProtocolEngine<CreatorSession> {
|
||||
throws DbException, FormatException {
|
||||
// If the session has already been aborted, do nothing
|
||||
if (s.getState() == ERROR) return s;
|
||||
// If we subscribe, stop syncing the private group with the contact
|
||||
// If we subscribe, make the private group invisible to the contact
|
||||
if (isSubscribedPrivateGroup(txn, s.getPrivateGroupId()))
|
||||
syncPrivateGroupWithContact(txn, s, false);
|
||||
setPrivateGroupVisibility(txn, s, INVISIBLE);
|
||||
// Send an ABORT message
|
||||
Message sent = sendAbortMessage(txn, s);
|
||||
// Move to the ERROR state
|
||||
|
||||
@@ -45,6 +45,7 @@ import java.util.Map.Entry;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.api.sync.Group.Visibility.SHARED;
|
||||
import static org.briarproject.privategroup.invitation.CreatorState.START;
|
||||
import static org.briarproject.privategroup.invitation.GroupInvitationConstants.GROUP_KEY_CONTACT_ID;
|
||||
import static org.briarproject.privategroup.invitation.MessageType.ABORT;
|
||||
@@ -110,7 +111,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
|
||||
if (db.containsGroup(txn, g.getId())) return;
|
||||
// Store the group and share it with the contact
|
||||
db.addGroup(txn, g);
|
||||
db.setVisibleToContact(txn, c.getId(), g.getId(), true);
|
||||
db.setGroupVisibility(txn, c.getId(), g.getId(), SHARED);
|
||||
// Attach the contact ID to the group
|
||||
BdfDictionary meta = new BdfDictionary();
|
||||
meta.put(GROUP_KEY_CONTACT_ID, c.getId().getInt());
|
||||
|
||||
@@ -25,6 +25,8 @@ import org.briarproject.api.system.Clock;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import static org.briarproject.api.sync.Group.Visibility.INVISIBLE;
|
||||
import static org.briarproject.api.sync.Group.Visibility.SHARED;
|
||||
import static org.briarproject.privategroup.invitation.InviteeState.DISSOLVED;
|
||||
import static org.briarproject.privategroup.invitation.InviteeState.ERROR;
|
||||
import static org.briarproject.privategroup.invitation.InviteeState.INVITED;
|
||||
@@ -157,8 +159,8 @@ class InviteeProtocolEngine extends AbstractProtocolEngine<InviteeSession> {
|
||||
try {
|
||||
// Subscribe to the private group
|
||||
subscribeToPrivateGroup(txn, inviteId);
|
||||
// Start syncing the private group with the contact
|
||||
syncPrivateGroupWithContact(txn, s, true);
|
||||
// Share the private group with the contact
|
||||
setPrivateGroupVisibility(txn, s, SHARED);
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e); // Invalid group metadata
|
||||
}
|
||||
@@ -228,8 +230,8 @@ class InviteeProtocolEngine extends AbstractProtocolEngine<InviteeSession> {
|
||||
if (!isValidDependency(s, m.getPreviousMessageId()))
|
||||
return abort(txn, s);
|
||||
try {
|
||||
// Stop syncing the private group with the contact
|
||||
syncPrivateGroupWithContact(txn, s, false);
|
||||
// Make the private group invisible to the contact
|
||||
setPrivateGroupVisibility(txn, s, INVISIBLE);
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e); // Invalid group metadata
|
||||
}
|
||||
@@ -247,9 +249,9 @@ class InviteeProtocolEngine extends AbstractProtocolEngine<InviteeSession> {
|
||||
if (s.getState() == ERROR) return s;
|
||||
// Mark any invite messages in the session unavailable to answer
|
||||
markInvitesUnavailableToAnswer(txn, s);
|
||||
// Stop syncing the private group with the contact, if we subscribe
|
||||
// If we subscribe, make the private group invisible to the contact
|
||||
if (isSubscribedPrivateGroup(txn, s.getPrivateGroupId()))
|
||||
syncPrivateGroupWithContact(txn, s, false);
|
||||
setPrivateGroupVisibility(txn, s, INVISIBLE);
|
||||
// Send an ABORT message
|
||||
Message sent = sendAbortMessage(txn, s);
|
||||
// Move to the ERROR state
|
||||
|
||||
@@ -20,6 +20,8 @@ import org.briarproject.api.system.Clock;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import static org.briarproject.api.sync.Group.Visibility.INVISIBLE;
|
||||
import static org.briarproject.api.sync.Group.Visibility.SHARED;
|
||||
import static org.briarproject.privategroup.invitation.PeerState.AWAIT_MEMBER;
|
||||
import static org.briarproject.privategroup.invitation.PeerState.BOTH_JOINED;
|
||||
import static org.briarproject.privategroup.invitation.PeerState.ERROR;
|
||||
@@ -178,8 +180,8 @@ class PeerProtocolEngine extends AbstractProtocolEngine<PeerSession> {
|
||||
// Send a JOIN message
|
||||
Message sent = sendJoinMessage(txn, s, false);
|
||||
try {
|
||||
// Start syncing the private group with the contact
|
||||
syncPrivateGroupWithContact(txn, s, true);
|
||||
// Share the private group with the contact
|
||||
setPrivateGroupVisibility(txn, s, SHARED);
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e); // Invalid group metadata
|
||||
}
|
||||
@@ -195,8 +197,8 @@ class PeerProtocolEngine extends AbstractProtocolEngine<PeerSession> {
|
||||
// Send a LEAVE message
|
||||
Message sent = sendLeaveMessage(txn, s, false);
|
||||
try {
|
||||
// Stop syncing the private group with the contact
|
||||
syncPrivateGroupWithContact(txn, s, false);
|
||||
// Make the private group invisible to the contact
|
||||
setPrivateGroupVisibility(txn, s, INVISIBLE);
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e); // Invalid group metadata
|
||||
}
|
||||
@@ -228,8 +230,8 @@ class PeerProtocolEngine extends AbstractProtocolEngine<PeerSession> {
|
||||
// Send a JOIN message
|
||||
Message sent = sendJoinMessage(txn, s, false);
|
||||
try {
|
||||
// Start syncing the private group with the contact
|
||||
syncPrivateGroupWithContact(txn, s, true);
|
||||
// Share the private group with the contact
|
||||
setPrivateGroupVisibility(txn, s, SHARED);
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e); // Invalid group metadata
|
||||
}
|
||||
@@ -263,8 +265,8 @@ class PeerProtocolEngine extends AbstractProtocolEngine<PeerSession> {
|
||||
return abort(txn, s);
|
||||
// Send a JOIN message
|
||||
Message sent = sendJoinMessage(txn, s, false);
|
||||
// Start syncing the private group with the contact
|
||||
syncPrivateGroupWithContact(txn, s, true);
|
||||
// Share the private group with the contact
|
||||
setPrivateGroupVisibility(txn, s, SHARED);
|
||||
// Mark the relationship visible to the group, revealed by contact
|
||||
relationshipRevealed(txn, s, true);
|
||||
// Move to the BOTH_JOINED state
|
||||
@@ -277,8 +279,8 @@ class PeerProtocolEngine extends AbstractProtocolEngine<PeerSession> {
|
||||
// The dependency, if any, must be the last remote message
|
||||
if (!isValidDependency(s, m.getPreviousMessageId()))
|
||||
return abort(txn, s);
|
||||
// Start syncing the private group with the contact
|
||||
syncPrivateGroupWithContact(txn, s, true);
|
||||
// Share the private group with the contact
|
||||
setPrivateGroupVisibility(txn, s, SHARED);
|
||||
// Mark the relationship visible to the group, revealed by us
|
||||
relationshipRevealed(txn, s, false);
|
||||
// Move to the BOTH_JOINED state
|
||||
@@ -314,8 +316,8 @@ class PeerProtocolEngine extends AbstractProtocolEngine<PeerSession> {
|
||||
// The dependency, if any, must be the last remote message
|
||||
if (!isValidDependency(s, m.getPreviousMessageId()))
|
||||
return abort(txn, s);
|
||||
// Stop syncing the private group with the contact
|
||||
syncPrivateGroupWithContact(txn, s, false);
|
||||
// Make the private group invisible to the contact
|
||||
setPrivateGroupVisibility(txn, s, INVISIBLE);
|
||||
// Move to the LOCAL_JOINED state
|
||||
return new PeerSession(s.getContactGroupId(), s.getPrivateGroupId(),
|
||||
s.getLastLocalMessageId(), m.getId(), s.getLocalTimestamp(),
|
||||
@@ -326,9 +328,9 @@ class PeerProtocolEngine extends AbstractProtocolEngine<PeerSession> {
|
||||
throws DbException, FormatException {
|
||||
// If the session has already been aborted, do nothing
|
||||
if (s.getState() == ERROR) return s;
|
||||
// Stop syncing the private group with the contact, if we subscribe
|
||||
// If we subscribe, make the private group invisible to the contact
|
||||
if (isSubscribedPrivateGroup(txn, s.getPrivateGroupId()))
|
||||
syncPrivateGroupWithContact(txn, s, false);
|
||||
setPrivateGroupVisibility(txn, s, INVISIBLE);
|
||||
// Send an ABORT message
|
||||
Message sent = sendAbortMessage(txn, s);
|
||||
// Move to the ERROR state
|
||||
|
||||
@@ -29,6 +29,8 @@ import java.util.Map.Entry;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.api.sync.Group.Visibility.SHARED;
|
||||
|
||||
class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
Client, AddContactHook, RemoveContactHook {
|
||||
|
||||
@@ -64,7 +66,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
if (db.containsGroup(txn, g.getId())) return;
|
||||
// Store the group and share it with the contact
|
||||
db.addGroup(txn, g);
|
||||
db.setVisibleToContact(txn, c.getId(), g.getId(), true);
|
||||
db.setGroupVisibility(txn, c.getId(), g.getId(), SHARED);
|
||||
// Copy the latest local properties into the group
|
||||
Map<TransportId, TransportProperties> local = getLocalProperties(txn);
|
||||
for (Entry<TransportId, TransportProperties> e : local.entrySet()) {
|
||||
|
||||
@@ -87,6 +87,8 @@ import static org.briarproject.api.sharing.SharingConstants.TO_BE_SHARED_BY_US;
|
||||
import static org.briarproject.api.sharing.SharingConstants.TYPE;
|
||||
import static org.briarproject.api.sharing.SharingMessage.BaseMessage;
|
||||
import static org.briarproject.api.sharing.SharingMessage.Invitation;
|
||||
import static org.briarproject.api.sync.Group.Visibility.INVISIBLE;
|
||||
import static org.briarproject.api.sync.Group.Visibility.SHARED;
|
||||
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
|
||||
import static org.briarproject.sharing.InviteeSessionState.State.AWAIT_LOCAL_RESPONSE;
|
||||
|
||||
@@ -159,7 +161,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
|
||||
if (db.containsGroup(txn, g.getId())) return;
|
||||
// Store the group and share it with the contact
|
||||
db.addGroup(txn, g);
|
||||
db.setVisibleToContact(txn, c.getId(), g.getId(), true);
|
||||
db.setGroupVisibility(txn, c.getId(), g.getId(), SHARED);
|
||||
// Attach the contact ID to the group
|
||||
BdfDictionary meta = new BdfDictionary();
|
||||
meta.put(CONTACT_ID, c.getId().getInt());
|
||||
@@ -908,20 +910,20 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
|
||||
// TODO we might want to call the add() method of the respective
|
||||
// manager here, because blogs add a description for example
|
||||
db.addGroup(txn, f.getGroup());
|
||||
db.setVisibleToContact(txn, contactId, f.getId(), true);
|
||||
db.setGroupVisibility(txn, contactId, f.getId(), SHARED);
|
||||
} else if (task == TASK_ADD_SHAREABLE_TO_LIST_TO_BE_SHARED_BY_US) {
|
||||
addToList(txn, groupId, TO_BE_SHARED_BY_US, f);
|
||||
} else if (task == TASK_REMOVE_SHAREABLE_FROM_LIST_TO_BE_SHARED_BY_US) {
|
||||
removeFromList(txn, groupId, TO_BE_SHARED_BY_US, f);
|
||||
} else if (task == TASK_SHARE_SHAREABLE) {
|
||||
db.setVisibleToContact(txn, contactId, f.getId(), true);
|
||||
db.setGroupVisibility(txn, contactId, f.getId(), SHARED);
|
||||
removeFromList(txn, groupId, TO_BE_SHARED_BY_US, f);
|
||||
addToList(txn, groupId, SHARED_BY_US, f);
|
||||
} else if (task == TASK_UNSHARE_SHAREABLE_SHARED_BY_US) {
|
||||
db.setVisibleToContact(txn, contactId, f.getId(), false);
|
||||
db.setGroupVisibility(txn, contactId, f.getId(), INVISIBLE);
|
||||
removeFromList(txn, groupId, SHARED_BY_US, f);
|
||||
} else if (task == TASK_UNSHARE_SHAREABLE_SHARED_WITH_US) {
|
||||
db.setVisibleToContact(txn, contactId, f.getId(), false);
|
||||
db.setGroupVisibility(txn, contactId, f.getId(), INVISIBLE);
|
||||
removeFromList(txn, groupId, SHARED_WITH_US, f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ import static org.briarproject.api.blogs.BlogConstants.KEY_TYPE;
|
||||
import static org.briarproject.api.blogs.MessageType.POST;
|
||||
import static org.briarproject.api.identity.Author.Status.VERIFIED;
|
||||
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.api.sync.Group.Visibility.SHARED;
|
||||
import static org.briarproject.blogs.BlogManagerImpl.CLIENT_ID;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@@ -102,25 +103,18 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
will(returnValue(blog1.getAuthor()));
|
||||
oneOf(blogFactory).createBlog(blog1.getAuthor());
|
||||
will(returnValue(blog1));
|
||||
oneOf(db).containsGroup(txn, blog1.getId());
|
||||
will(returnValue(false));
|
||||
oneOf(db).addGroup(txn, blog1.getGroup());
|
||||
oneOf(db).getContacts(txn, blog1.getAuthor().getId());
|
||||
will(returnValue(contactIds));
|
||||
oneOf(db).setVisibleToContact(txn, contactId, blog1.getId(), true);
|
||||
oneOf(db).getContacts(txn);
|
||||
will(returnValue(contacts));
|
||||
oneOf(blogFactory).createBlog(blog2.getAuthor());
|
||||
will(returnValue(blog2));
|
||||
oneOf(db).containsGroup(txn, blog2.getId());
|
||||
will(returnValue(false));
|
||||
oneOf(db).addGroup(txn, blog2.getGroup());
|
||||
oneOf(db).setVisibleToContact(txn, contactId, blog2.getId(), true);
|
||||
oneOf(db).getLocalAuthor(txn, blog1.getAuthor().getId());
|
||||
oneOf(db).setGroupVisibility(txn, contactId, blog2.getId(), SHARED);
|
||||
oneOf(identityManager).getLocalAuthor(txn);
|
||||
will(returnValue(blog1.getAuthor()));
|
||||
oneOf(blogFactory).createBlog(blog1.getAuthor());
|
||||
will(returnValue(blog1));
|
||||
oneOf(db).setVisibleToContact(txn, contactId, blog1.getId(), true);
|
||||
oneOf(db).setGroupVisibility(txn, contactId, blog1.getId(), SHARED);
|
||||
}});
|
||||
|
||||
blogManager.createLocalState(txn);
|
||||
|
||||
@@ -60,6 +60,9 @@ import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.api.sync.Group.Visibility.INVISIBLE;
|
||||
import static org.briarproject.api.sync.Group.Visibility.SHARED;
|
||||
import static org.briarproject.api.sync.Group.Visibility.VISIBLE;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.UNKNOWN;
|
||||
import static org.briarproject.api.transport.TransportConstants.REORDERING_WINDOW_SIZE;
|
||||
@@ -170,7 +173,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
// removeGroup()
|
||||
oneOf(database).containsGroup(txn, groupId);
|
||||
will(returnValue(true));
|
||||
oneOf(database).getVisibility(txn, groupId);
|
||||
oneOf(database).getGroupVisibility(txn, groupId);
|
||||
will(returnValue(Collections.emptyList()));
|
||||
oneOf(database).removeGroup(txn, groupId);
|
||||
oneOf(eventBus).broadcast(with(any(GroupRemovedEvent.class)));
|
||||
@@ -267,7 +270,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
will(returnValue(false));
|
||||
oneOf(database).addMessage(txn, message, DELIVERED, true);
|
||||
oneOf(database).mergeMessageMetadata(txn, messageId, metadata);
|
||||
oneOf(database).getVisibility(txn, groupId);
|
||||
oneOf(database).getGroupVisibility(txn, groupId);
|
||||
will(returnValue(Collections.singletonList(contactId)));
|
||||
oneOf(database).removeOfferedMessage(txn, contactId, messageId);
|
||||
will(returnValue(false));
|
||||
@@ -403,7 +406,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
|
||||
transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.isVisibleToContact(transaction, contactId, groupId);
|
||||
db.getGroupVisibility(transaction, contactId, groupId);
|
||||
fail();
|
||||
} catch (NoSuchContactException expected) {
|
||||
// Expected
|
||||
@@ -487,7 +490,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
|
||||
transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.setVisibleToContact(transaction, contactId, groupId, true);
|
||||
db.setGroupVisibility(transaction, contactId, groupId, SHARED);
|
||||
fail();
|
||||
} catch (NoSuchContactException expected) {
|
||||
// Expected
|
||||
@@ -560,14 +563,13 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
// Check whether the group is in the DB (which it's not)
|
||||
exactly(9).of(database).startTransaction();
|
||||
exactly(8).of(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
exactly(9).of(database).containsGroup(txn, groupId);
|
||||
exactly(8).of(database).containsGroup(txn, groupId);
|
||||
will(returnValue(false));
|
||||
exactly(9).of(database).abortTransaction(txn);
|
||||
// This is needed for getMessageStatus(), isVisibleToContact(), and
|
||||
// setVisibleToContact() to proceed
|
||||
exactly(3).of(database).containsContact(txn, contactId);
|
||||
exactly(8).of(database).abortTransaction(txn);
|
||||
// This is needed for getMessageStatus() and setGroupVisibility()
|
||||
exactly(2).of(database).containsContact(txn, contactId);
|
||||
will(returnValue(true));
|
||||
}});
|
||||
DatabaseComponent db = createDatabaseComponent(database, eventBus,
|
||||
@@ -623,16 +625,6 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
db.endTransaction(transaction);
|
||||
}
|
||||
|
||||
transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.isVisibleToContact(transaction, contactId, groupId);
|
||||
fail();
|
||||
} catch (NoSuchGroupException expected) {
|
||||
// Expected
|
||||
} finally {
|
||||
db.endTransaction(transaction);
|
||||
}
|
||||
|
||||
transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.mergeGroupMetadata(transaction, groupId, metadata);
|
||||
@@ -655,7 +647,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
|
||||
transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.setVisibleToContact(transaction, contactId, groupId, true);
|
||||
db.setGroupVisibility(transaction, contactId, groupId, SHARED);
|
||||
fail();
|
||||
} catch (NoSuchGroupException expected) {
|
||||
// Expected
|
||||
@@ -924,6 +916,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
Transaction transaction = db.startTransaction(false);
|
||||
try {
|
||||
Ack a = db.generateAck(transaction, contactId, 123);
|
||||
assertNotNull(a);
|
||||
assertEquals(messagesToAck, a.getMessageIds());
|
||||
db.commitTransaction(transaction);
|
||||
} finally {
|
||||
@@ -1005,6 +998,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
Transaction transaction = db.startTransaction(false);
|
||||
try {
|
||||
Offer o = db.generateOffer(transaction, contactId, 123, maxLatency);
|
||||
assertNotNull(o);
|
||||
assertEquals(ids, o.getMessageIds());
|
||||
db.commitTransaction(transaction);
|
||||
} finally {
|
||||
@@ -1039,6 +1033,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
Transaction transaction = db.startTransaction(false);
|
||||
try {
|
||||
Request r = db.generateRequest(transaction, contactId, 123);
|
||||
assertNotNull(r);
|
||||
assertEquals(ids, r.getMessageIds());
|
||||
db.commitTransaction(transaction);
|
||||
} finally {
|
||||
@@ -1139,12 +1134,12 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
// First time
|
||||
oneOf(database).containsContact(txn, contactId);
|
||||
will(returnValue(true));
|
||||
oneOf(database).containsVisibleGroup(txn, contactId, groupId);
|
||||
will(returnValue(true));
|
||||
oneOf(database).getGroupVisibility(txn, contactId, groupId);
|
||||
will(returnValue(VISIBLE));
|
||||
oneOf(database).containsMessage(txn, messageId);
|
||||
will(returnValue(false));
|
||||
oneOf(database).addMessage(txn, message, UNKNOWN, false);
|
||||
oneOf(database).getVisibility(txn, groupId);
|
||||
oneOf(database).getGroupVisibility(txn, groupId);
|
||||
will(returnValue(Collections.singletonList(contactId)));
|
||||
oneOf(database).removeOfferedMessage(txn, contactId, messageId);
|
||||
will(returnValue(false));
|
||||
@@ -1152,8 +1147,8 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
// Second time
|
||||
oneOf(database).containsContact(txn, contactId);
|
||||
will(returnValue(true));
|
||||
oneOf(database).containsVisibleGroup(txn, contactId, groupId);
|
||||
will(returnValue(true));
|
||||
oneOf(database).getGroupVisibility(txn, contactId, groupId);
|
||||
will(returnValue(VISIBLE));
|
||||
oneOf(database).containsMessage(txn, messageId);
|
||||
will(returnValue(true));
|
||||
oneOf(database).raiseSeenFlag(txn, contactId, messageId);
|
||||
@@ -1195,8 +1190,8 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
will(returnValue(true));
|
||||
oneOf(database).containsMessage(txn, messageId);
|
||||
will(returnValue(true));
|
||||
oneOf(database).containsVisibleGroup(txn, contactId, groupId);
|
||||
will(returnValue(true));
|
||||
oneOf(database).getGroupVisibility(txn, contactId, groupId);
|
||||
will(returnValue(VISIBLE));
|
||||
// The message wasn't stored but it must still be acked
|
||||
oneOf(database).raiseSeenFlag(txn, contactId, messageId);
|
||||
oneOf(database).raiseAckFlag(txn, contactId, messageId);
|
||||
@@ -1230,8 +1225,8 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
will(returnValue(txn));
|
||||
oneOf(database).containsContact(txn, contactId);
|
||||
will(returnValue(true));
|
||||
oneOf(database).containsVisibleGroup(txn, contactId, groupId);
|
||||
will(returnValue(false));
|
||||
oneOf(database).getGroupVisibility(txn, contactId, groupId);
|
||||
will(returnValue(INVISIBLE));
|
||||
oneOf(database).commitTransaction(txn);
|
||||
}});
|
||||
DatabaseComponent db = createDatabaseComponent(database, eventBus,
|
||||
@@ -1350,9 +1345,9 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
will(returnValue(true));
|
||||
oneOf(database).containsGroup(txn, groupId);
|
||||
will(returnValue(true));
|
||||
oneOf(database).containsVisibleGroup(txn, contactId, groupId);
|
||||
will(returnValue(false)); // Not yet visible
|
||||
oneOf(database).addVisibility(txn, contactId, groupId);
|
||||
oneOf(database).getGroupVisibility(txn, contactId, groupId);
|
||||
will(returnValue(INVISIBLE)); // Not yet visible
|
||||
oneOf(database).addGroupVisibility(txn, contactId, groupId, false);
|
||||
oneOf(database).getMessageIds(txn, groupId);
|
||||
will(returnValue(Collections.singletonList(messageId)));
|
||||
oneOf(database).removeOfferedMessage(txn, contactId, messageId);
|
||||
@@ -1367,7 +1362,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
|
||||
Transaction transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.setVisibleToContact(transaction, contactId, groupId, true);
|
||||
db.setGroupVisibility(transaction, contactId, groupId, VISIBLE);
|
||||
db.commitTransaction(transaction);
|
||||
} finally {
|
||||
db.endTransaction(transaction);
|
||||
@@ -1391,8 +1386,8 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
will(returnValue(true));
|
||||
oneOf(database).containsGroup(txn, groupId);
|
||||
will(returnValue(true));
|
||||
oneOf(database).containsVisibleGroup(txn, contactId, groupId);
|
||||
will(returnValue(true)); // Already visible
|
||||
oneOf(database).getGroupVisibility(txn, contactId, groupId);
|
||||
will(returnValue(VISIBLE)); // Already visible
|
||||
oneOf(database).commitTransaction(txn);
|
||||
}});
|
||||
DatabaseComponent db = createDatabaseComponent(database, eventBus,
|
||||
@@ -1400,7 +1395,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
|
||||
Transaction transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.setVisibleToContact(transaction, contactId, groupId, true);
|
||||
db.setGroupVisibility(transaction, contactId, groupId, VISIBLE);
|
||||
db.commitTransaction(transaction);
|
||||
} finally {
|
||||
db.endTransaction(transaction);
|
||||
@@ -1666,7 +1661,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
oneOf(database).containsMessage(txn, messageId);
|
||||
will(returnValue(false));
|
||||
oneOf(database).addMessage(txn, message, DELIVERED, true);
|
||||
oneOf(database).getVisibility(txn, groupId);
|
||||
oneOf(database).getGroupVisibility(txn, groupId);
|
||||
will(returnValue(Collections.singletonList(contactId)));
|
||||
oneOf(database).mergeMessageMetadata(txn, messageId, metadata);
|
||||
oneOf(database).removeOfferedMessage(txn, contactId, messageId);
|
||||
|
||||
@@ -45,6 +45,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static org.briarproject.api.db.Metadata.REMOVE;
|
||||
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.api.sync.Group.Visibility.INVISIBLE;
|
||||
import static org.briarproject.api.sync.Group.Visibility.SHARED;
|
||||
import static org.briarproject.api.sync.Group.Visibility.VISIBLE;
|
||||
import static org.briarproject.api.sync.SyncConstants.MAX_MESSAGE_LENGTH;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
|
||||
@@ -171,12 +174,12 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
|
||||
// Add a contact, a group and a message
|
||||
// Add a contact, a shared group and a shared message
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addVisibility(txn, contactId, groupId);
|
||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||
db.addMessage(txn, message, DELIVERED, true);
|
||||
|
||||
// The message has no status yet, so it should not be sendable
|
||||
@@ -209,12 +212,12 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
|
||||
// Add a contact, a group and an unvalidated message
|
||||
// Add a contact, a shared group and a shared but unvalidated message
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addVisibility(txn, contactId, groupId);
|
||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||
db.addMessage(txn, message, UNKNOWN, true);
|
||||
db.addStatus(txn, contactId, messageId, false, false);
|
||||
|
||||
@@ -251,16 +254,68 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendableMessagesMustBeShared() throws Exception {
|
||||
public void testSendableMessagesMustHaveSharedGroup() throws Exception {
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
|
||||
// Add a contact, a group and an unshared message
|
||||
// Add a contact, an invisible group and a shared message
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addVisibility(txn, contactId, groupId);
|
||||
db.addMessage(txn, message, DELIVERED, true);
|
||||
db.addStatus(txn, contactId, messageId, false, false);
|
||||
|
||||
// The group is invisible, so the message should not be sendable
|
||||
Collection<MessageId> ids = db.getMessagesToSend(txn, contactId,
|
||||
ONE_MEGABYTE);
|
||||
assertTrue(ids.isEmpty());
|
||||
ids = db.getMessagesToOffer(txn, contactId, 100);
|
||||
assertTrue(ids.isEmpty());
|
||||
|
||||
// Making the group visible should not make the message sendable
|
||||
db.addGroupVisibility(txn, contactId, groupId, false);
|
||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE);
|
||||
assertTrue(ids.isEmpty());
|
||||
ids = db.getMessagesToOffer(txn, contactId, 100);
|
||||
assertTrue(ids.isEmpty());
|
||||
|
||||
// Sharing the group should make the message sendable
|
||||
db.setGroupVisibility(txn, contactId, groupId, true);
|
||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE);
|
||||
assertEquals(Collections.singletonList(messageId), ids);
|
||||
ids = db.getMessagesToOffer(txn, contactId, 100);
|
||||
assertEquals(Collections.singletonList(messageId), ids);
|
||||
|
||||
// Unsharing the group should make the message unsendable
|
||||
db.setGroupVisibility(txn, contactId, groupId, false);
|
||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE);
|
||||
assertTrue(ids.isEmpty());
|
||||
ids = db.getMessagesToOffer(txn, contactId, 100);
|
||||
assertTrue(ids.isEmpty());
|
||||
|
||||
// Making the group invisible should make the message unsendable
|
||||
db.removeGroupVisibility(txn, contactId, groupId);
|
||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE);
|
||||
assertTrue(ids.isEmpty());
|
||||
ids = db.getMessagesToOffer(txn, contactId, 100);
|
||||
assertTrue(ids.isEmpty());
|
||||
|
||||
db.commitTransaction(txn);
|
||||
db.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendableMessagesMustBeShared() throws Exception {
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
|
||||
// Add a contact, a shared group and an unshared message
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||
db.addMessage(txn, message, DELIVERED, false);
|
||||
db.addStatus(txn, contactId, messageId, false, false);
|
||||
|
||||
@@ -287,12 +342,12 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
|
||||
// Add a contact, a group and a message
|
||||
// Add a contact, a shared group and a shared message
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addVisibility(txn, contactId, groupId);
|
||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||
db.addMessage(txn, message, DELIVERED, true);
|
||||
db.addStatus(txn, contactId, messageId, false, false);
|
||||
|
||||
@@ -314,12 +369,12 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
|
||||
// Add a contact and a group
|
||||
// Add a contact and a visible group
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addVisibility(txn, contactId, groupId);
|
||||
db.addGroupVisibility(txn, contactId, groupId, false);
|
||||
|
||||
// Add some messages to ack
|
||||
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
||||
@@ -351,12 +406,12 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
|
||||
// Add a contact, a group and a message
|
||||
// Add a contact, a shared group and a shared message
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addVisibility(txn, contactId, groupId);
|
||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||
db.addMessage(txn, message, DELIVERED, true);
|
||||
db.addStatus(txn, contactId, messageId, false, false);
|
||||
|
||||
@@ -515,12 +570,12 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
|
||||
// Add a contact and a group
|
||||
// Add a contact and a shared group
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addVisibility(txn, contactId, groupId);
|
||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||
|
||||
// The message is not in the database
|
||||
assertFalse(db.containsVisibleMessage(txn, contactId, messageId));
|
||||
@@ -569,7 +624,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVisibility() throws Exception {
|
||||
public void testGroupVisibility() throws Exception {
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
|
||||
@@ -580,52 +635,33 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
db.addGroup(txn, group);
|
||||
|
||||
// The group should not be visible to the contact
|
||||
assertEquals(Collections.emptyList(), db.getVisibility(txn, groupId));
|
||||
assertEquals(INVISIBLE, db.getGroupVisibility(txn, contactId, groupId));
|
||||
assertEquals(Collections.emptyList(),
|
||||
db.getGroupVisibility(txn, groupId));
|
||||
|
||||
// Make the group visible to the contact
|
||||
db.addVisibility(txn, contactId, groupId);
|
||||
db.addGroupVisibility(txn, contactId, groupId, false);
|
||||
assertEquals(VISIBLE, db.getGroupVisibility(txn, contactId, groupId));
|
||||
assertEquals(Collections.singletonList(contactId),
|
||||
db.getVisibility(txn, groupId));
|
||||
db.getGroupVisibility(txn, groupId));
|
||||
|
||||
// Share the group with the contact
|
||||
db.setGroupVisibility(txn, contactId, groupId, true);
|
||||
assertEquals(SHARED, db.getGroupVisibility(txn, contactId, groupId));
|
||||
assertEquals(Collections.singletonList(contactId),
|
||||
db.getGroupVisibility(txn, groupId));
|
||||
|
||||
// Unshare the group with the contact
|
||||
db.setGroupVisibility(txn, contactId, groupId, false);
|
||||
assertEquals(VISIBLE, db.getGroupVisibility(txn, contactId, groupId));
|
||||
assertEquals(Collections.singletonList(contactId),
|
||||
db.getGroupVisibility(txn, groupId));
|
||||
|
||||
// Make the group invisible again
|
||||
db.removeVisibility(txn, contactId, groupId);
|
||||
assertEquals(Collections.emptyList(), db.getVisibility(txn, groupId));
|
||||
|
||||
db.commitTransaction(txn);
|
||||
db.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleGroupChanges() throws Exception {
|
||||
// Create some groups
|
||||
List<Group> groups = new ArrayList<>();
|
||||
for (int i = 0; i < 100; i++) {
|
||||
GroupId id = new GroupId(TestUtils.getRandomId());
|
||||
ClientId clientId = new ClientId(TestUtils.getRandomString(5));
|
||||
byte[] descriptor = new byte[0];
|
||||
groups.add(new Group(id, clientId, descriptor));
|
||||
}
|
||||
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
|
||||
// Add a contact and the groups
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
true, true));
|
||||
for (Group g : groups) db.addGroup(txn, g);
|
||||
|
||||
// Make the groups visible to the contact
|
||||
Collections.shuffle(groups);
|
||||
for (Group g : groups) db.addVisibility(txn, contactId, g.getId());
|
||||
|
||||
// Make some of the groups invisible to the contact and remove them all
|
||||
Collections.shuffle(groups);
|
||||
for (Group g : groups) {
|
||||
if (Math.random() < 0.5)
|
||||
db.removeVisibility(txn, contactId, g.getId());
|
||||
db.removeGroup(txn, g.getId());
|
||||
}
|
||||
db.removeGroupVisibility(txn, contactId, groupId);
|
||||
assertEquals(INVISIBLE, db.getGroupVisibility(txn, contactId, groupId));
|
||||
assertEquals(Collections.emptyList(),
|
||||
db.getGroupVisibility(txn, groupId));
|
||||
|
||||
db.commitTransaction(txn);
|
||||
db.close();
|
||||
@@ -1144,15 +1180,15 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
metadata1.put("foo", new byte[]{'b', 'a', 'r'});
|
||||
db.mergeMessageMetadata(txn, messageId1, metadata1);
|
||||
|
||||
for (int i = 1; i <= 2; i++) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
Metadata query;
|
||||
if (i == 1) {
|
||||
if (i == 0) {
|
||||
// Query the metadata with an empty query
|
||||
query = new Metadata();
|
||||
} else {
|
||||
// Query for foo
|
||||
query = new Metadata();
|
||||
query.put("foo", metadata.get("foo"));
|
||||
query.put("foo", new byte[]{'b', 'a', 'r'});
|
||||
}
|
||||
|
||||
db.setMessageState(txn, messageId, DELIVERED);
|
||||
@@ -1160,32 +1196,39 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
Map<MessageId, Metadata> all =
|
||||
db.getMessageMetadata(txn, groupId, query);
|
||||
assertEquals(2, all.size());
|
||||
assertEquals(2, all.get(messageId).size());
|
||||
assertEquals(1, all.get(messageId1).size());
|
||||
assertMetadataEquals(metadata, all.get(messageId));
|
||||
assertMetadataEquals(metadata1, all.get(messageId1));
|
||||
|
||||
// No metadata for unknown messages
|
||||
db.setMessageState(txn, messageId, UNKNOWN);
|
||||
db.setMessageState(txn, messageId1, UNKNOWN);
|
||||
all = db.getMessageMetadata(txn, groupId, query);
|
||||
assertTrue(all.isEmpty());
|
||||
assertEquals(1, all.size());
|
||||
assertMetadataEquals(metadata1, all.get(messageId1));
|
||||
|
||||
// No metadata for invalid messages
|
||||
db.setMessageState(txn, messageId, INVALID);
|
||||
db.setMessageState(txn, messageId1, INVALID);
|
||||
all = db.getMessageMetadata(txn, groupId, query);
|
||||
assertTrue(all.isEmpty());
|
||||
assertEquals(1, all.size());
|
||||
assertMetadataEquals(metadata1, all.get(messageId1));
|
||||
|
||||
// No metadata for pending messages
|
||||
db.setMessageState(txn, messageId, PENDING);
|
||||
db.setMessageState(txn, messageId1, PENDING);
|
||||
all = db.getMessageMetadata(txn, groupId, query);
|
||||
assertTrue(all.isEmpty());
|
||||
assertEquals(1, all.size());
|
||||
assertMetadataEquals(metadata1, all.get(messageId1));
|
||||
}
|
||||
|
||||
db.commitTransaction(txn);
|
||||
db.close();
|
||||
}
|
||||
|
||||
private void assertMetadataEquals(Metadata m1, Metadata m2) {
|
||||
assertEquals(m1.keySet(), m2.keySet());
|
||||
for (Entry<String, byte[]> e : m1.entrySet()) {
|
||||
assertArrayEquals(e.getValue(), m2.get(e.getKey()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageDependencies() throws Exception {
|
||||
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
||||
@@ -1398,16 +1441,12 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
|
||||
// Add a contact
|
||||
// Add a contact, a shared group and a shared message
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
true, true));
|
||||
|
||||
// Add a group and make it visible to the contact
|
||||
db.addGroup(txn, group);
|
||||
db.addVisibility(txn, contactId, groupId);
|
||||
|
||||
// Add a message to the group
|
||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||
db.addMessage(txn, message, DELIVERED, true);
|
||||
db.addStatus(txn, contactId, messageId, false, false);
|
||||
|
||||
@@ -1471,33 +1510,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGroupsVisibleToContacts() throws Exception {
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
|
||||
// Add a contact and a group
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
|
||||
// The group should not be visible to the contact
|
||||
assertFalse(db.containsVisibleGroup(txn, contactId, groupId));
|
||||
|
||||
// Make the group visible to the contact
|
||||
db.addVisibility(txn, contactId, groupId);
|
||||
assertTrue(db.containsVisibleGroup(txn, contactId, groupId));
|
||||
|
||||
// Make the group invisible to the contact
|
||||
db.removeVisibility(txn, contactId, groupId);
|
||||
assertFalse(db.containsVisibleGroup(txn, contactId, groupId));
|
||||
|
||||
db.commitTransaction(txn);
|
||||
db.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDifferentLocalPseudonymsCanHaveTheSameContact()
|
||||
public void testDifferentLocalAuthorsCanHaveTheSameContact()
|
||||
throws Exception {
|
||||
AuthorId localAuthorId1 = new AuthorId(TestUtils.getRandomId());
|
||||
LocalAuthor localAuthor1 = new LocalAuthor(localAuthorId1, "Carol",
|
||||
@@ -1506,11 +1519,11 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
|
||||
// Add two local pseudonyms
|
||||
// Add two local authors
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
db.addLocalAuthor(txn, localAuthor1);
|
||||
|
||||
// Add the same contact for each local pseudonym
|
||||
// Add the same contact for each local author
|
||||
ContactId contactId =
|
||||
db.addContact(txn, author, localAuthorId, true, true);
|
||||
ContactId contactId1 =
|
||||
@@ -1531,12 +1544,12 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
|
||||
// Add a contact, a group and a message
|
||||
// Add a contact, a shared group and a shared message
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addVisibility(txn, contactId, groupId);
|
||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||
db.addMessage(txn, message, DELIVERED, true);
|
||||
db.addStatus(txn, contactId, messageId, false, false);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user