Auto-delete PrivateGroup invitations and responses as well

This commit is contained in:
Torsten Grote
2021-03-01 13:57:23 -03:00
parent 3dc3d384d3
commit e36f275be7
4 changed files with 93 additions and 17 deletions

View File

@@ -132,6 +132,10 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
privateGroup.getCreator(), privateGroup.getSalt(), text,
signature, timer);
sendMessage(txn, m, INVITE, privateGroup.getId(), true, timer);
// Set the auto-delete timer duration on the message
if (timer != NO_AUTO_DELETE_TIMER) {
db.setCleanupTimerDuration(txn, m.getId(), timer);
}
} else {
m = messageEncoder.encodeInviteMessage(s.getContactGroupId(),
privateGroup.getId(), timestamp, privateGroup.getName(),
@@ -162,6 +166,10 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
s.getLastLocalMessageId(), timer);
sendMessage(txn, m, JOIN, s.getPrivateGroupId(), visibleInUi,
timer);
// Set the auto-delete timer duration on the message
if (timer != NO_AUTO_DELETE_TIMER) {
db.setCleanupTimerDuration(txn, m.getId(), timer);
}
} else {
m = messageEncoder.encodeJoinMessage(s.getContactGroupId(),
s.getPrivateGroupId(), localTimestamp,
@@ -191,6 +199,10 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
s.getLastLocalMessageId(), timer);
sendMessage(txn, m, LEAVE, s.getPrivateGroupId(), visibleInUi,
timer);
// Set the auto-delete timer duration on the message
if (timer != NO_AUTO_DELETE_TIMER) {
db.setCleanupTimerDuration(txn, m.getId(), timer);
}
} else {
m = messageEncoder.encodeLeaveMessage(s.getContactGroupId(),
s.getPrivateGroupId(), localTimestamp,

View File

@@ -1,6 +1,7 @@
package org.briarproject.briar.privategroup.invitation;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.cleanup.CleanupHook;
import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.client.ContactGroupFactory;
import org.briarproject.bramble.api.contact.Contact;
@@ -24,6 +25,7 @@ import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.sync.MessageStatus;
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
import org.briarproject.bramble.api.versioning.ClientVersioningManager.ClientVersioningHook;
import org.briarproject.briar.api.autodelete.event.ConversationMessagesDeletedEvent;
import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.api.conversation.ConversationMessageHeader;
@@ -52,6 +54,7 @@ import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.briar.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
import static org.briarproject.briar.privategroup.invitation.CreatorState.START;
import static org.briarproject.briar.privategroup.invitation.MessageType.ABORT;
import static org.briarproject.briar.privategroup.invitation.MessageType.INVITE;
@@ -65,7 +68,7 @@ import static org.briarproject.briar.privategroup.invitation.Role.PEER;
@NotNullByDefault
class GroupInvitationManagerImpl extends ConversationClientImpl
implements GroupInvitationManager, OpenDatabaseHook, ContactHook,
PrivateGroupHook, ClientVersioningHook {
PrivateGroupHook, ClientVersioningHook, CleanupHook {
private final ClientVersioningManager clientVersioningManager;
private final ContactGroupFactory contactGroupFactory;
@@ -148,6 +151,11 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
BdfDictionary bdfMeta) throws DbException, FormatException {
// Parse the metadata
MessageMetadata meta = messageParser.parseMetadata(bdfMeta);
// set the clean-up timer that will be started when message gets read
long timer = meta.getAutoDeleteTimer();
if (timer != NO_AUTO_DELETE_TIMER) {
db.setCleanupTimerDuration(txn, m.getId(), timer);
}
// Look up the session, if there is one
SessionId sessionId = getSessionId(meta.getPrivateGroupId());
StoredSession ss = getSession(txn, m.getGroupId(), sessionId);
@@ -301,7 +309,12 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
@Override
public void respondToInvitation(ContactId c, SessionId sessionId,
boolean accept) throws DbException {
Transaction txn = db.startTransaction(false);
db.transaction(false,
txn -> respondToInvitation(txn, c, sessionId, accept));
}
private void respondToInvitation(Transaction txn, ContactId c,
SessionId sessionId, boolean accept) throws DbException {
try {
// Look up the session
Contact contact = db.getContact(txn, c);
@@ -316,11 +329,8 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
else session = inviteeEngine.onLeaveAction(txn, session);
// Store the updated session
storeSession(txn, ss.storageId, session);
db.commitTransaction(txn);
} catch (FormatException e) {
throw new DbException(e);
} finally {
db.endTransaction(txn);
}
}
@@ -686,7 +696,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
// get ID of the contact group
GroupId g = getContactGroup(db.getContact(txn, c)).getId();
// get metadata for all messages in the
// get metadata for all messages in the group
// (these are sessions *and* protocol messages)
Map<MessageId, BdfDictionary> metadata;
try {
@@ -762,6 +772,59 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
return result;
}
@Override
public void deleteMessages(Transaction txn, GroupId g,
Collection<MessageId> messageIds) throws DbException {
ContactId c;
Map<SessionId, DeletableSession> sessions = new HashMap<>();
try {
// get the ContactId from the given GroupId
c = clientHelper.getContactId(txn, g);
// get sessions for all messages to be deleted
for (MessageId messageId : messageIds) {
BdfDictionary d = clientHelper
.getMessageMetadataAsDictionary(txn, messageId);
MessageMetadata messageMetadata =
messageParser.parseMetadata(d);
if (!messageMetadata.isVisibleInConversation())
throw new IllegalArgumentException();
SessionId sessionId =
getSessionId(messageMetadata.getPrivateGroupId());
DeletableSession deletableSession = sessions.get(sessionId);
if (deletableSession == null) {
StoredSession ss = getSession(txn, g, sessionId);
if (ss == null) throw new DbException();
BdfDictionary sessionMeta = clientHelper
.getMessageMetadataAsDictionary(txn, ss.storageId);
Session<?> session = sessionParser
.parseSession(g, sessionMeta);
deletableSession = new DeletableSession(session.getState());
sessions.put(sessionId, deletableSession);
}
deletableSession.messages.add(messageId);
}
} catch (FormatException e) {
throw new DbException(e);
}
// delete given visible messages in sessions and auto-respond before
for (Entry<SessionId, DeletableSession> entry : sessions.entrySet()) {
DeletableSession session = entry.getValue();
// decline invitee sessions waiting for a response before
if (session.state instanceof InviteeState &&
session.state.isAwaitingResponse()) {
respondToInvitation(txn, c, entry.getKey(), false);
}
for (MessageId m : session.messages) {
db.deleteMessage(txn, m);
db.deleteMessageMetadata(txn, m);
}
}
recalculateGroupCount(txn, g);
txn.attach(new ConversationMessagesDeletedEvent(c, messageIds));
}
@Override
public Set<MessageId> getMessageIds(Transaction txn, ContactId c)
throws DbException {

View File

@@ -1,5 +1,6 @@
package org.briarproject.briar.privategroup.invitation;
import org.briarproject.bramble.api.cleanup.CleanupManager;
import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.contact.ContactManager;
import org.briarproject.bramble.api.data.MetadataEncoder;
@@ -41,7 +42,8 @@ public class GroupInvitationModule {
ValidationManager validationManager, ContactManager contactManager,
PrivateGroupManager privateGroupManager,
ConversationManager conversationManager,
ClientVersioningManager clientVersioningManager) {
ClientVersioningManager clientVersioningManager,
CleanupManager cleanupManager) {
lifecycleManager.registerOpenDatabaseHook(groupInvitationManager);
validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION,
groupInvitationManager);
@@ -56,6 +58,8 @@ public class GroupInvitationModule {
PrivateGroupManager.MAJOR_VERSION,
PrivateGroupManager.MINOR_VERSION,
groupInvitationManager.getPrivateGroupClientVersioningHook());
cleanupManager.registerCleanupHook(CLIENT_ID, MAJOR_VERSION,
groupInvitationManager);
return groupInvitationManager;
}

View File

@@ -21,6 +21,7 @@ import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
import org.briarproject.bramble.test.BrambleMockTestCase;
import org.briarproject.bramble.test.DbExpectations;
import org.briarproject.bramble.test.TestUtils;
import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.client.SessionId;
@@ -329,10 +330,11 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
context.checking(new Expectations() {{
oneOf(messageParser).parseMetadata(meta);
will(returnValue(messageMetadata));
oneOf(messageMetadata).getAutoDeleteTimer();
will(returnValue(NO_AUTO_DELETE_TIMER));
oneOf(messageMetadata).getPrivateGroupId();
will(returnValue(privateGroup.getId()));
}});
}
private void expectIncomingMessage(Role role, MessageType type)
@@ -530,15 +532,13 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
public void testRespondToInvitationWithoutSession() throws Exception {
SessionId sessionId = new SessionId(getRandomId());
context.checking(new Expectations() {{
oneOf(db).startTransaction(false);
will(returnValue(txn));
context.checking(new DbExpectations() {{
oneOf(db).transaction(with(false), withDbRunnable(txn));
oneOf(db).getContact(txn, contactId);
will(returnValue(contact));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact);
will(returnValue(contactGroup));
oneOf(db).endTransaction(txn);
}});
expectGetSession(noResults, sessionId, contactGroup.getId());
@@ -582,9 +582,8 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
private void expectRespondToInvitation(SessionId sessionId, boolean accept)
throws Exception {
expectGetSession(oneResult, sessionId, contactGroup.getId());
context.checking(new Expectations() {{
oneOf(db).startTransaction(false);
will(returnValue(txn));
context.checking(new DbExpectations() {{
oneOf(db).transaction(with(false), withDbRunnable(txn));
oneOf(db).getContact(txn, contactId);
will(returnValue(contact));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
@@ -596,8 +595,6 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
if (accept) oneOf(inviteeEngine).onJoinAction(txn, inviteeSession);
else oneOf(inviteeEngine).onLeaveAction(txn, inviteeSession);
will(returnValue(inviteeSession));
oneOf(db).commitTransaction(txn);
oneOf(db).endTransaction(txn);
}});
expectStoreSession(inviteeSession, storageMessage.getId());
}