mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-19 06:09:55 +01:00
Clean up Introduction Session States
for introducer when both introducees have been deleted. Closes #372
This commit is contained in:
@@ -832,6 +832,106 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIntroduceesRemovedCleanup() throws Exception {
|
||||||
|
startLifecycles();
|
||||||
|
try {
|
||||||
|
// Add Identities
|
||||||
|
addDefaultIdentities();
|
||||||
|
|
||||||
|
// Add Transport Properties
|
||||||
|
addTransportProperties();
|
||||||
|
|
||||||
|
// Add introducees as contacts
|
||||||
|
contactId1 = contactManager0.addContact(author1,
|
||||||
|
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
contactId2 = contactManager0.addContact(author2,
|
||||||
|
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
// Add introducer back
|
||||||
|
contactId0 = contactManager1.addContact(author0,
|
||||||
|
author1.getId(), master, clock.currentTimeMillis(), true,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
ContactId contactId02 = contactManager2.addContact(author0,
|
||||||
|
author2.getId(), master, clock.currentTimeMillis(), true,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
assertTrue(contactId0.equals(contactId02));
|
||||||
|
|
||||||
|
// listen to events
|
||||||
|
IntroducerListener listener0 = new IntroducerListener();
|
||||||
|
t0.getEventBus().addListener(listener0);
|
||||||
|
IntroduceeListener listener1 = new IntroduceeListener(1, true);
|
||||||
|
t1.getEventBus().addListener(listener1);
|
||||||
|
IntroduceeListener listener2 = new IntroduceeListener(2, true);
|
||||||
|
t2.getEventBus().addListener(listener2);
|
||||||
|
|
||||||
|
// make introduction
|
||||||
|
long time = clock.currentTimeMillis();
|
||||||
|
Contact introducee1 = contactManager0.getContact(contactId1);
|
||||||
|
Contact introducee2 = contactManager0.getContact(contactId2);
|
||||||
|
introductionManager0
|
||||||
|
.makeIntroduction(introducee1, introducee2, "Hi!", time);
|
||||||
|
|
||||||
|
// sync first request message
|
||||||
|
deliverMessage(sync0, contactId0, sync1, contactId1, "0 to 1");
|
||||||
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
|
assertTrue(listener1.requestReceived);
|
||||||
|
|
||||||
|
// get database and local group for introducee
|
||||||
|
DatabaseComponent db0 = t0.getDatabaseComponent();
|
||||||
|
IntroductionGroupFactory groupFactory0 =
|
||||||
|
t0.getIntroductionGroupFactory();
|
||||||
|
Group group1 = groupFactory0.createLocalGroup();
|
||||||
|
|
||||||
|
// get local session state messages
|
||||||
|
Map<MessageId, Metadata> map;
|
||||||
|
Transaction txn = db0.startTransaction(false);
|
||||||
|
try {
|
||||||
|
map = db0.getMessageMetadata(txn, group1.getId());
|
||||||
|
txn.setComplete();
|
||||||
|
} finally {
|
||||||
|
db0.endTransaction(txn);
|
||||||
|
}
|
||||||
|
// check that we have one session state
|
||||||
|
assertEquals(1, map.size());
|
||||||
|
|
||||||
|
// introducer removes introducee1
|
||||||
|
contactManager0.removeContact(contactId1);
|
||||||
|
|
||||||
|
// get local session state messages again
|
||||||
|
txn = db0.startTransaction(false);
|
||||||
|
try {
|
||||||
|
map = db0.getMessageMetadata(txn, group1.getId());
|
||||||
|
txn.setComplete();
|
||||||
|
} finally {
|
||||||
|
db0.endTransaction(txn);
|
||||||
|
}
|
||||||
|
// make sure local state is still there
|
||||||
|
assertEquals(1, map.size());
|
||||||
|
|
||||||
|
// introducer removes other introducee
|
||||||
|
contactManager0.removeContact(contactId2);
|
||||||
|
|
||||||
|
// get local session state messages again
|
||||||
|
txn = db0.startTransaction(false);
|
||||||
|
try {
|
||||||
|
map = db0.getMessageMetadata(txn, group1.getId());
|
||||||
|
txn.setComplete();
|
||||||
|
} finally {
|
||||||
|
db0.endTransaction(txn);
|
||||||
|
}
|
||||||
|
// make sure local state is gone now
|
||||||
|
assertEquals(0, map.size());
|
||||||
|
} finally {
|
||||||
|
stopLifecycles();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO add a test for faking responses when #256 is implemented
|
// TODO add a test for faking responses when #256 is implemented
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
|||||||
@@ -9,10 +9,12 @@ import org.briarproject.api.contact.ContactId;
|
|||||||
import org.briarproject.api.contact.ContactManager.AddContactHook;
|
import org.briarproject.api.contact.ContactManager.AddContactHook;
|
||||||
import org.briarproject.api.contact.ContactManager.RemoveContactHook;
|
import org.briarproject.api.contact.ContactManager.RemoveContactHook;
|
||||||
import org.briarproject.api.data.BdfDictionary;
|
import org.briarproject.api.data.BdfDictionary;
|
||||||
|
import org.briarproject.api.data.BdfEntry;
|
||||||
import org.briarproject.api.data.BdfList;
|
import org.briarproject.api.data.BdfList;
|
||||||
import org.briarproject.api.data.MetadataParser;
|
import org.briarproject.api.data.MetadataParser;
|
||||||
import org.briarproject.api.db.DatabaseComponent;
|
import org.briarproject.api.db.DatabaseComponent;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
|
import org.briarproject.api.db.NoSuchContactException;
|
||||||
import org.briarproject.api.db.NoSuchMessageException;
|
import org.briarproject.api.db.NoSuchMessageException;
|
||||||
import org.briarproject.api.db.Transaction;
|
import org.briarproject.api.db.Transaction;
|
||||||
import org.briarproject.api.identity.AuthorId;
|
import org.briarproject.api.identity.AuthorId;
|
||||||
@@ -136,29 +138,58 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removingContact(Transaction txn, Contact c) throws DbException {
|
public void removingContact(Transaction txn, Contact c) throws DbException {
|
||||||
// check for open sessions with that contact and abort those
|
GroupId gId = introductionGroupFactory.createLocalGroup().getId();
|
||||||
Long id = (long) c.getId().getInt();
|
|
||||||
|
// search for session states where c introduced us
|
||||||
|
BdfDictionary query = BdfDictionary.of(
|
||||||
|
new BdfEntry(ROLE, ROLE_INTRODUCEE),
|
||||||
|
new BdfEntry(CONTACT_ID_1, c.getId().getInt())
|
||||||
|
);
|
||||||
try {
|
try {
|
||||||
Map<MessageId, BdfDictionary> map = clientHelper
|
Map<MessageId, BdfDictionary> map = clientHelper
|
||||||
.getMessageMetadataAsDictionary(txn,
|
.getMessageMetadataAsDictionary(txn, gId, query);
|
||||||
introductionGroupFactory.createLocalGroup().getId());
|
for (Map.Entry<MessageId, BdfDictionary> entry : map.entrySet()) {
|
||||||
|
// delete states if introducee removes introducer
|
||||||
|
deleteMessage(txn, entry.getKey());
|
||||||
|
}
|
||||||
|
} catch (FormatException e) {
|
||||||
|
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for open sessions with c and abort those,
|
||||||
|
// so the other introducee knows
|
||||||
|
query = BdfDictionary.of(
|
||||||
|
new BdfEntry(ROLE, ROLE_INTRODUCER)
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
Map<MessageId, BdfDictionary> map = clientHelper
|
||||||
|
.getMessageMetadataAsDictionary(txn, gId, query);
|
||||||
for (Map.Entry<MessageId, BdfDictionary> entry : map.entrySet()) {
|
for (Map.Entry<MessageId, BdfDictionary> entry : map.entrySet()) {
|
||||||
BdfDictionary d = entry.getValue();
|
BdfDictionary d = entry.getValue();
|
||||||
long role = d.getLong(ROLE, -1L);
|
ContactId c1 = new ContactId(d.getLong(CONTACT_ID_1).intValue());
|
||||||
if (role != ROLE_INTRODUCER) {
|
ContactId c2 = new ContactId(d.getLong(CONTACT_ID_2).intValue());
|
||||||
if (d.getLong(CONTACT_ID_1).equals(id)) {
|
|
||||||
// delete states if introducee removes introducer
|
|
||||||
deleteMessage(txn, entry.getKey());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (d.getLong(CONTACT_ID_1).equals(id) ||
|
|
||||||
d.getLong(CONTACT_ID_2).equals(id)) {
|
|
||||||
|
|
||||||
|
if (c1.equals(c.getId()) || c2.equals(c.getId())) {
|
||||||
IntroducerProtocolState state = IntroducerProtocolState
|
IntroducerProtocolState state = IntroducerProtocolState
|
||||||
.fromValue(d.getLong(STATE).intValue());
|
.fromValue(d.getLong(STATE).intValue());
|
||||||
|
// abort protocol if still ongoing
|
||||||
if (IntroducerProtocolState.isOngoing(state)) {
|
if (IntroducerProtocolState.isOngoing(state)) {
|
||||||
introducerManager.abort(txn, d);
|
introducerManager.abort(txn, d);
|
||||||
}
|
}
|
||||||
|
// also delete state if both contacts have been deleted
|
||||||
|
if (c1.equals(c.getId())) {
|
||||||
|
try {
|
||||||
|
db.getContact(txn, c2);
|
||||||
|
} catch (NoSuchContactException e) {
|
||||||
|
deleteMessage(txn, entry.getKey());
|
||||||
|
}
|
||||||
|
} else if (c2.equals(c.getId())) {
|
||||||
|
try {
|
||||||
|
db.getContact(txn, c1);
|
||||||
|
} catch (NoSuchContactException e) {
|
||||||
|
deleteMessage(txn, entry.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
|
|||||||
Reference in New Issue
Block a user