mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-21 07:09:56 +01:00
Auto-delete PrivateGroup invitations and responses as well
This commit is contained in:
@@ -132,6 +132,10 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
|
|||||||
privateGroup.getCreator(), privateGroup.getSalt(), text,
|
privateGroup.getCreator(), privateGroup.getSalt(), text,
|
||||||
signature, timer);
|
signature, timer);
|
||||||
sendMessage(txn, m, INVITE, privateGroup.getId(), true, 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 {
|
} else {
|
||||||
m = messageEncoder.encodeInviteMessage(s.getContactGroupId(),
|
m = messageEncoder.encodeInviteMessage(s.getContactGroupId(),
|
||||||
privateGroup.getId(), timestamp, privateGroup.getName(),
|
privateGroup.getId(), timestamp, privateGroup.getName(),
|
||||||
@@ -162,6 +166,10 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
|
|||||||
s.getLastLocalMessageId(), timer);
|
s.getLastLocalMessageId(), timer);
|
||||||
sendMessage(txn, m, JOIN, s.getPrivateGroupId(), visibleInUi,
|
sendMessage(txn, m, JOIN, s.getPrivateGroupId(), visibleInUi,
|
||||||
timer);
|
timer);
|
||||||
|
// Set the auto-delete timer duration on the message
|
||||||
|
if (timer != NO_AUTO_DELETE_TIMER) {
|
||||||
|
db.setCleanupTimerDuration(txn, m.getId(), timer);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
m = messageEncoder.encodeJoinMessage(s.getContactGroupId(),
|
m = messageEncoder.encodeJoinMessage(s.getContactGroupId(),
|
||||||
s.getPrivateGroupId(), localTimestamp,
|
s.getPrivateGroupId(), localTimestamp,
|
||||||
@@ -191,6 +199,10 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
|
|||||||
s.getLastLocalMessageId(), timer);
|
s.getLastLocalMessageId(), timer);
|
||||||
sendMessage(txn, m, LEAVE, s.getPrivateGroupId(), visibleInUi,
|
sendMessage(txn, m, LEAVE, s.getPrivateGroupId(), visibleInUi,
|
||||||
timer);
|
timer);
|
||||||
|
// Set the auto-delete timer duration on the message
|
||||||
|
if (timer != NO_AUTO_DELETE_TIMER) {
|
||||||
|
db.setCleanupTimerDuration(txn, m.getId(), timer);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
m = messageEncoder.encodeLeaveMessage(s.getContactGroupId(),
|
m = messageEncoder.encodeLeaveMessage(s.getContactGroupId(),
|
||||||
s.getPrivateGroupId(), localTimestamp,
|
s.getPrivateGroupId(), localTimestamp,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.briarproject.briar.privategroup.invitation;
|
package org.briarproject.briar.privategroup.invitation;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
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.ClientHelper;
|
||||||
import org.briarproject.bramble.api.client.ContactGroupFactory;
|
import org.briarproject.bramble.api.client.ContactGroupFactory;
|
||||||
import org.briarproject.bramble.api.contact.Contact;
|
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.sync.MessageStatus;
|
||||||
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
|
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
|
||||||
import org.briarproject.bramble.api.versioning.ClientVersioningManager.ClientVersioningHook;
|
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.MessageTracker;
|
||||||
import org.briarproject.briar.api.client.SessionId;
|
import org.briarproject.briar.api.client.SessionId;
|
||||||
import org.briarproject.briar.api.conversation.ConversationMessageHeader;
|
import org.briarproject.briar.api.conversation.ConversationMessageHeader;
|
||||||
@@ -52,6 +54,7 @@ import javax.annotation.concurrent.Immutable;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
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.CreatorState.START;
|
||||||
import static org.briarproject.briar.privategroup.invitation.MessageType.ABORT;
|
import static org.briarproject.briar.privategroup.invitation.MessageType.ABORT;
|
||||||
import static org.briarproject.briar.privategroup.invitation.MessageType.INVITE;
|
import static org.briarproject.briar.privategroup.invitation.MessageType.INVITE;
|
||||||
@@ -65,7 +68,7 @@ import static org.briarproject.briar.privategroup.invitation.Role.PEER;
|
|||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class GroupInvitationManagerImpl extends ConversationClientImpl
|
class GroupInvitationManagerImpl extends ConversationClientImpl
|
||||||
implements GroupInvitationManager, OpenDatabaseHook, ContactHook,
|
implements GroupInvitationManager, OpenDatabaseHook, ContactHook,
|
||||||
PrivateGroupHook, ClientVersioningHook {
|
PrivateGroupHook, ClientVersioningHook, CleanupHook {
|
||||||
|
|
||||||
private final ClientVersioningManager clientVersioningManager;
|
private final ClientVersioningManager clientVersioningManager;
|
||||||
private final ContactGroupFactory contactGroupFactory;
|
private final ContactGroupFactory contactGroupFactory;
|
||||||
@@ -148,6 +151,11 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
|
|||||||
BdfDictionary bdfMeta) throws DbException, FormatException {
|
BdfDictionary bdfMeta) throws DbException, FormatException {
|
||||||
// Parse the metadata
|
// Parse the metadata
|
||||||
MessageMetadata meta = messageParser.parseMetadata(bdfMeta);
|
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
|
// Look up the session, if there is one
|
||||||
SessionId sessionId = getSessionId(meta.getPrivateGroupId());
|
SessionId sessionId = getSessionId(meta.getPrivateGroupId());
|
||||||
StoredSession ss = getSession(txn, m.getGroupId(), sessionId);
|
StoredSession ss = getSession(txn, m.getGroupId(), sessionId);
|
||||||
@@ -301,7 +309,12 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
|
|||||||
@Override
|
@Override
|
||||||
public void respondToInvitation(ContactId c, SessionId sessionId,
|
public void respondToInvitation(ContactId c, SessionId sessionId,
|
||||||
boolean accept) throws DbException {
|
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 {
|
try {
|
||||||
// Look up the session
|
// Look up the session
|
||||||
Contact contact = db.getContact(txn, c);
|
Contact contact = db.getContact(txn, c);
|
||||||
@@ -316,11 +329,8 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
|
|||||||
else session = inviteeEngine.onLeaveAction(txn, session);
|
else session = inviteeEngine.onLeaveAction(txn, session);
|
||||||
// Store the updated session
|
// Store the updated session
|
||||||
storeSession(txn, ss.storageId, session);
|
storeSession(txn, ss.storageId, session);
|
||||||
db.commitTransaction(txn);
|
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -686,7 +696,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
|
|||||||
// get ID of the contact group
|
// get ID of the contact group
|
||||||
GroupId g = getContactGroup(db.getContact(txn, c)).getId();
|
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)
|
// (these are sessions *and* protocol messages)
|
||||||
Map<MessageId, BdfDictionary> metadata;
|
Map<MessageId, BdfDictionary> metadata;
|
||||||
try {
|
try {
|
||||||
@@ -762,6 +772,59 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
|
|||||||
return result;
|
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
|
@Override
|
||||||
public Set<MessageId> getMessageIds(Transaction txn, ContactId c)
|
public Set<MessageId> getMessageIds(Transaction txn, ContactId c)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.briarproject.briar.privategroup.invitation;
|
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.client.ClientHelper;
|
||||||
import org.briarproject.bramble.api.contact.ContactManager;
|
import org.briarproject.bramble.api.contact.ContactManager;
|
||||||
import org.briarproject.bramble.api.data.MetadataEncoder;
|
import org.briarproject.bramble.api.data.MetadataEncoder;
|
||||||
@@ -41,7 +42,8 @@ public class GroupInvitationModule {
|
|||||||
ValidationManager validationManager, ContactManager contactManager,
|
ValidationManager validationManager, ContactManager contactManager,
|
||||||
PrivateGroupManager privateGroupManager,
|
PrivateGroupManager privateGroupManager,
|
||||||
ConversationManager conversationManager,
|
ConversationManager conversationManager,
|
||||||
ClientVersioningManager clientVersioningManager) {
|
ClientVersioningManager clientVersioningManager,
|
||||||
|
CleanupManager cleanupManager) {
|
||||||
lifecycleManager.registerOpenDatabaseHook(groupInvitationManager);
|
lifecycleManager.registerOpenDatabaseHook(groupInvitationManager);
|
||||||
validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION,
|
validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION,
|
||||||
groupInvitationManager);
|
groupInvitationManager);
|
||||||
@@ -56,6 +58,8 @@ public class GroupInvitationModule {
|
|||||||
PrivateGroupManager.MAJOR_VERSION,
|
PrivateGroupManager.MAJOR_VERSION,
|
||||||
PrivateGroupManager.MINOR_VERSION,
|
PrivateGroupManager.MINOR_VERSION,
|
||||||
groupInvitationManager.getPrivateGroupClientVersioningHook());
|
groupInvitationManager.getPrivateGroupClientVersioningHook());
|
||||||
|
cleanupManager.registerCleanupHook(CLIENT_ID, MAJOR_VERSION,
|
||||||
|
groupInvitationManager);
|
||||||
return groupInvitationManager;
|
return groupInvitationManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import org.briarproject.bramble.api.sync.Message;
|
|||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
|
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
|
||||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||||
|
import org.briarproject.bramble.test.DbExpectations;
|
||||||
import org.briarproject.bramble.test.TestUtils;
|
import org.briarproject.bramble.test.TestUtils;
|
||||||
import org.briarproject.briar.api.client.MessageTracker;
|
import org.briarproject.briar.api.client.MessageTracker;
|
||||||
import org.briarproject.briar.api.client.SessionId;
|
import org.briarproject.briar.api.client.SessionId;
|
||||||
@@ -329,10 +330,11 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
|
|||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(messageParser).parseMetadata(meta);
|
oneOf(messageParser).parseMetadata(meta);
|
||||||
will(returnValue(messageMetadata));
|
will(returnValue(messageMetadata));
|
||||||
|
oneOf(messageMetadata).getAutoDeleteTimer();
|
||||||
|
will(returnValue(NO_AUTO_DELETE_TIMER));
|
||||||
oneOf(messageMetadata).getPrivateGroupId();
|
oneOf(messageMetadata).getPrivateGroupId();
|
||||||
will(returnValue(privateGroup.getId()));
|
will(returnValue(privateGroup.getId()));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void expectIncomingMessage(Role role, MessageType type)
|
private void expectIncomingMessage(Role role, MessageType type)
|
||||||
@@ -530,15 +532,13 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
|
|||||||
public void testRespondToInvitationWithoutSession() throws Exception {
|
public void testRespondToInvitationWithoutSession() throws Exception {
|
||||||
SessionId sessionId = new SessionId(getRandomId());
|
SessionId sessionId = new SessionId(getRandomId());
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getContact(txn, contactId);
|
oneOf(db).getContact(txn, contactId);
|
||||||
will(returnValue(contact));
|
will(returnValue(contact));
|
||||||
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
|
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
|
||||||
MAJOR_VERSION, contact);
|
MAJOR_VERSION, contact);
|
||||||
will(returnValue(contactGroup));
|
will(returnValue(contactGroup));
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
expectGetSession(noResults, sessionId, contactGroup.getId());
|
expectGetSession(noResults, sessionId, contactGroup.getId());
|
||||||
|
|
||||||
@@ -582,9 +582,8 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
|
|||||||
private void expectRespondToInvitation(SessionId sessionId, boolean accept)
|
private void expectRespondToInvitation(SessionId sessionId, boolean accept)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
expectGetSession(oneResult, sessionId, contactGroup.getId());
|
expectGetSession(oneResult, sessionId, contactGroup.getId());
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getContact(txn, contactId);
|
oneOf(db).getContact(txn, contactId);
|
||||||
will(returnValue(contact));
|
will(returnValue(contact));
|
||||||
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
|
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
|
||||||
@@ -596,8 +595,6 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
|
|||||||
if (accept) oneOf(inviteeEngine).onJoinAction(txn, inviteeSession);
|
if (accept) oneOf(inviteeEngine).onJoinAction(txn, inviteeSession);
|
||||||
else oneOf(inviteeEngine).onLeaveAction(txn, inviteeSession);
|
else oneOf(inviteeEngine).onLeaveAction(txn, inviteeSession);
|
||||||
will(returnValue(inviteeSession));
|
will(returnValue(inviteeSession));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
expectStoreSession(inviteeSession, storageMessage.getId());
|
expectStoreSession(inviteeSession, storageMessage.getId());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user