mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-17 13:19:52 +01:00
Throw an exception if a raw message has been deleted.
This commit is contained in:
@@ -16,8 +16,6 @@ import org.briarproject.bramble.api.sync.MessageId;
|
|||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public interface ClientHelper {
|
public interface ClientHelper {
|
||||||
|
|
||||||
@@ -32,16 +30,12 @@ public interface ClientHelper {
|
|||||||
|
|
||||||
Message createMessageForStoringMetadata(GroupId g);
|
Message createMessageForStoringMetadata(GroupId g);
|
||||||
|
|
||||||
@Nullable
|
|
||||||
Message getMessage(MessageId m) throws DbException;
|
Message getMessage(MessageId m) throws DbException;
|
||||||
|
|
||||||
@Nullable
|
|
||||||
Message getMessage(Transaction txn, MessageId m) throws DbException;
|
Message getMessage(Transaction txn, MessageId m) throws DbException;
|
||||||
|
|
||||||
@Nullable
|
|
||||||
BdfList getMessageAsList(MessageId m) throws DbException, FormatException;
|
BdfList getMessageAsList(MessageId m) throws DbException, FormatException;
|
||||||
|
|
||||||
@Nullable
|
|
||||||
BdfList getMessageAsList(Transaction txn, MessageId m) throws DbException,
|
BdfList getMessageAsList(Transaction txn, MessageId m) throws DbException,
|
||||||
FormatException;
|
FormatException;
|
||||||
|
|
||||||
|
|||||||
@@ -298,12 +298,12 @@ public interface DatabaseComponent {
|
|||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the message with the given ID, in serialised form, or null if
|
* Returns the message with the given ID, in serialised form.
|
||||||
* the message has been deleted.
|
|
||||||
* <p/>
|
* <p/>
|
||||||
* Read-only.
|
* Read-only.
|
||||||
|
*
|
||||||
|
* @throws MessageDeletedException if the message has been deleted
|
||||||
*/
|
*/
|
||||||
@Nullable
|
|
||||||
byte[] getRawMessage(Transaction txn, MessageId m) throws DbException;
|
byte[] getRawMessage(Transaction txn, MessageId m) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package org.briarproject.bramble.api.db;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when a message that has been deleted is requested from the database.
|
||||||
|
* This exception may occur due to concurrent updates and does not indicate a
|
||||||
|
* database error.
|
||||||
|
*/
|
||||||
|
public class MessageDeletedException extends DbException {
|
||||||
|
}
|
||||||
@@ -127,9 +127,7 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Message getMessage(Transaction txn, MessageId m) throws DbException {
|
public Message getMessage(Transaction txn, MessageId m) throws DbException {
|
||||||
byte[] raw = db.getRawMessage(txn, m);
|
return messageFactory.createMessage(m, db.getRawMessage(txn, m));
|
||||||
if (raw == null) return null;
|
|
||||||
return messageFactory.createMessage(m, raw);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -150,7 +148,6 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
public BdfList getMessageAsList(Transaction txn, MessageId m)
|
public BdfList getMessageAsList(Transaction txn, MessageId m)
|
||||||
throws DbException, FormatException {
|
throws DbException, FormatException {
|
||||||
byte[] raw = db.getRawMessage(txn, m);
|
byte[] raw = db.getRawMessage(txn, m);
|
||||||
if (raw == null) return null;
|
|
||||||
return toList(raw, MESSAGE_HEADER_LENGTH,
|
return toList(raw, MESSAGE_HEADER_LENGTH,
|
||||||
raw.length - MESSAGE_HEADER_LENGTH);
|
raw.length - MESSAGE_HEADER_LENGTH);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import org.briarproject.bramble.api.crypto.SecretKey;
|
|||||||
import org.briarproject.bramble.api.db.DataTooNewException;
|
import org.briarproject.bramble.api.db.DataTooNewException;
|
||||||
import org.briarproject.bramble.api.db.DataTooOldException;
|
import org.briarproject.bramble.api.db.DataTooOldException;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
|
import org.briarproject.bramble.api.db.MessageDeletedException;
|
||||||
import org.briarproject.bramble.api.db.Metadata;
|
import org.briarproject.bramble.api.db.Metadata;
|
||||||
import org.briarproject.bramble.api.db.MigrationListener;
|
import org.briarproject.bramble.api.db.MigrationListener;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
@@ -465,12 +466,12 @@ interface Database<T> {
|
|||||||
long getNextSendTime(T txn, ContactId c) throws DbException;
|
long getNextSendTime(T txn, ContactId c) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the message with the given ID, in serialised form, or null if
|
* Returns the message with the given ID, in serialised form.
|
||||||
* the message has been deleted.
|
|
||||||
* <p/>
|
* <p/>
|
||||||
* Read-only.
|
* Read-only.
|
||||||
|
*
|
||||||
|
* @throws MessageDeletedException if the message has been deleted
|
||||||
*/
|
*/
|
||||||
@Nullable
|
|
||||||
byte[] getRawMessage(T txn, MessageId m) throws DbException;
|
byte[] getRawMessage(T txn, MessageId m) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -487,7 +487,6 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
return db.getMessagesToShare(txn);
|
return db.getMessagesToShare(txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] getRawMessage(Transaction transaction, MessageId m)
|
public byte[] getRawMessage(Transaction transaction, MessageId m)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import org.briarproject.bramble.api.db.DataTooNewException;
|
|||||||
import org.briarproject.bramble.api.db.DataTooOldException;
|
import org.briarproject.bramble.api.db.DataTooOldException;
|
||||||
import org.briarproject.bramble.api.db.DbClosedException;
|
import org.briarproject.bramble.api.db.DbClosedException;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
|
import org.briarproject.bramble.api.db.MessageDeletedException;
|
||||||
import org.briarproject.bramble.api.db.Metadata;
|
import org.briarproject.bramble.api.db.Metadata;
|
||||||
import org.briarproject.bramble.api.db.MigrationListener;
|
import org.briarproject.bramble.api.db.MigrationListener;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
@@ -2019,7 +2020,6 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
|
||||||
public byte[] getRawMessage(Connection txn, MessageId m)
|
public byte[] getRawMessage(Connection txn, MessageId m)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
@@ -2034,6 +2034,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (rs.next()) throw new DbStateException();
|
if (rs.next()) throw new DbStateException();
|
||||||
rs.close();
|
rs.close();
|
||||||
ps.close();
|
ps.close();
|
||||||
|
if (raw == null) throw new MessageDeletedException();
|
||||||
return raw;
|
return raw;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs);
|
||||||
|
|||||||
@@ -164,7 +164,6 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
for (Entry<TransportId, LatestUpdate> e : latest.entrySet()) {
|
for (Entry<TransportId, LatestUpdate> e : latest.entrySet()) {
|
||||||
BdfList message = clientHelper.getMessageAsList(txn,
|
BdfList message = clientHelper.getMessageAsList(txn,
|
||||||
e.getValue().messageId);
|
e.getValue().messageId);
|
||||||
if (message == null) throw new DbException();
|
|
||||||
local.put(e.getKey(), parseProperties(message));
|
local.put(e.getKey(), parseProperties(message));
|
||||||
}
|
}
|
||||||
return local;
|
return local;
|
||||||
@@ -187,7 +186,6 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
// Retrieve and parse the latest local properties
|
// Retrieve and parse the latest local properties
|
||||||
BdfList message = clientHelper.getMessageAsList(txn,
|
BdfList message = clientHelper.getMessageAsList(txn,
|
||||||
latest.messageId);
|
latest.messageId);
|
||||||
if (message == null) throw new DbException();
|
|
||||||
p = parseProperties(message);
|
p = parseProperties(message);
|
||||||
}
|
}
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
@@ -227,7 +225,6 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
// Retrieve and parse the latest remote properties
|
// Retrieve and parse the latest remote properties
|
||||||
BdfList message =
|
BdfList message =
|
||||||
clientHelper.getMessageAsList(txn, latest.messageId);
|
clientHelper.getMessageAsList(txn, latest.messageId);
|
||||||
if (message == null) throw new DbException();
|
|
||||||
return parseProperties(message);
|
return parseProperties(message);
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
@@ -265,7 +262,6 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
} else {
|
} else {
|
||||||
BdfList message = clientHelper.getMessageAsList(txn,
|
BdfList message = clientHelper.getMessageAsList(txn,
|
||||||
latest.messageId);
|
latest.messageId);
|
||||||
if (message == null) throw new DbException();
|
|
||||||
TransportProperties old = parseProperties(message);
|
TransportProperties old = parseProperties(message);
|
||||||
merged = new TransportProperties(old);
|
merged = new TransportProperties(old);
|
||||||
merged.putAll(p);
|
merged.putAll(p);
|
||||||
|
|||||||
@@ -129,7 +129,6 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
|||||||
try {
|
try {
|
||||||
MessageId id = unvalidated.poll();
|
MessageId id = unvalidated.poll();
|
||||||
byte[] raw = db.getRawMessage(txn, id);
|
byte[] raw = db.getRawMessage(txn, id);
|
||||||
if (raw == null) throw new DbException();
|
|
||||||
m = messageFactory.createMessage(id, raw);
|
m = messageFactory.createMessage(id, raw);
|
||||||
g = db.getGroup(txn, m.getGroupId());
|
g = db.getGroup(txn, m.getGroupId());
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
@@ -198,7 +197,6 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
|||||||
invalidate = getDependentsToInvalidate(txn, id);
|
invalidate = getDependentsToInvalidate(txn, id);
|
||||||
} else if (allDelivered) {
|
} else if (allDelivered) {
|
||||||
byte[] raw = db.getRawMessage(txn, id);
|
byte[] raw = db.getRawMessage(txn, id);
|
||||||
if (raw == null) throw new DbException();
|
|
||||||
Message m = messageFactory.createMessage(id, raw);
|
Message m = messageFactory.createMessage(id, raw);
|
||||||
Group g = db.getGroup(txn, m.getGroupId());
|
Group g = db.getGroup(txn, m.getGroupId());
|
||||||
ClientId c = g.getClientId();
|
ClientId c = g.getClientId();
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, Client,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stopService() throws ServiceException {
|
public void stopService() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -274,9 +274,7 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, Client,
|
|||||||
private List<ClientVersion> loadClientVersions(Transaction txn,
|
private List<ClientVersion> loadClientVersions(Transaction txn,
|
||||||
MessageId m) throws DbException {
|
MessageId m) throws DbException {
|
||||||
try {
|
try {
|
||||||
BdfList body = clientHelper.getMessageAsList(txn, m);
|
return parseClientVersions(clientHelper.getMessageAsList(txn, m));
|
||||||
if (body == null) throw new DbException();
|
|
||||||
return parseClientVersions(body);
|
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
@@ -359,9 +357,7 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, Client,
|
|||||||
|
|
||||||
private Update loadUpdate(Transaction txn, MessageId m) throws DbException {
|
private Update loadUpdate(Transaction txn, MessageId m) throws DbException {
|
||||||
try {
|
try {
|
||||||
BdfList body = clientHelper.getMessageAsList(txn, m);
|
return parseUpdate(clientHelper.getMessageAsList(txn, m));
|
||||||
if (body == null) throw new DbException();
|
|
||||||
return parseUpdate(body);
|
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import org.briarproject.bramble.api.contact.ContactId;
|
|||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.db.DatabaseConfig;
|
import org.briarproject.bramble.api.db.DatabaseConfig;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
|
import org.briarproject.bramble.api.db.MessageDeletedException;
|
||||||
import org.briarproject.bramble.api.db.Metadata;
|
import org.briarproject.bramble.api.db.Metadata;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
@@ -1654,8 +1655,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
ids = db.getMessagesToOffer(txn, contactId, 100);
|
ids = db.getMessagesToOffer(txn, contactId, 100);
|
||||||
assertEquals(singletonList(messageId), ids);
|
assertEquals(singletonList(messageId), ids);
|
||||||
|
|
||||||
// The raw message should not be null
|
// The raw message should be available
|
||||||
assertNotNull(db.getRawMessage(txn, messageId));
|
assertArrayEquals(raw, db.getRawMessage(txn, messageId));
|
||||||
|
|
||||||
// Delete the message
|
// Delete the message
|
||||||
db.deleteMessage(txn, messageId);
|
db.deleteMessage(txn, messageId);
|
||||||
@@ -1669,8 +1670,13 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
ids = db.getMessagesToOffer(txn, contactId, 100);
|
ids = db.getMessagesToOffer(txn, contactId, 100);
|
||||||
assertTrue(ids.isEmpty());
|
assertTrue(ids.isEmpty());
|
||||||
|
|
||||||
// The raw message should be null
|
// Requesting the raw message should throw an exception
|
||||||
assertNull(db.getRawMessage(txn, messageId));
|
try {
|
||||||
|
db.getRawMessage(txn, messageId);
|
||||||
|
fail();
|
||||||
|
} catch (MessageDeletedException expected) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
db.close();
|
db.close();
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addingContact(Transaction txn, Contact c) throws DbException {
|
public void addingContact(Transaction txn, Contact c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -311,7 +311,6 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
|
|||||||
|
|
||||||
// Get body of message to be wrapped
|
// Get body of message to be wrapped
|
||||||
BdfList body = clientHelper.getMessageAsList(txn, header.getId());
|
BdfList body = clientHelper.getMessageAsList(txn, header.getId());
|
||||||
if (body == null) throw new DbException();
|
|
||||||
long timestamp = header.getTimestamp();
|
long timestamp = header.getTimestamp();
|
||||||
Message wrappedMessage;
|
Message wrappedMessage;
|
||||||
|
|
||||||
@@ -459,9 +458,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
|
|||||||
@Override
|
@Override
|
||||||
public String getPostBody(MessageId m) throws DbException {
|
public String getPostBody(MessageId m) throws DbException {
|
||||||
try {
|
try {
|
||||||
BdfList message = clientHelper.getMessageAsList(m);
|
return getPostBody(clientHelper.getMessageAsList(m));
|
||||||
if (message == null) throw new DbException();
|
|
||||||
return getPostBody(message);
|
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -204,10 +204,7 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
|
|||||||
@Override
|
@Override
|
||||||
public String getPostBody(MessageId m) throws DbException {
|
public String getPostBody(MessageId m) throws DbException {
|
||||||
try {
|
try {
|
||||||
// Parent ID, author, forum post body, signature
|
return getPostBody(clientHelper.getMessageAsList(m));
|
||||||
BdfList body = clientHelper.getMessageAsList(m);
|
|
||||||
if (body == null) throw new DbException();
|
|
||||||
return getPostBody(body);
|
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -463,7 +463,6 @@ class IntroductionManagerImpl extends ConversationClientImpl
|
|||||||
author = session.getRemote().author;
|
author = session.getRemote().author;
|
||||||
} else throw new AssertionError();
|
} else throw new AssertionError();
|
||||||
Message msg = clientHelper.getMessage(txn, m);
|
Message msg = clientHelper.getMessage(txn, m);
|
||||||
if (msg == null) throw new AssertionError();
|
|
||||||
BdfList body = clientHelper.toList(msg);
|
BdfList body = clientHelper.toList(msg);
|
||||||
RequestMessage rm = messageParser.parseRequestMessage(msg, body);
|
RequestMessage rm = messageParser.parseRequestMessage(msg, body);
|
||||||
String message = rm.getMessage();
|
String message = rm.getMessage();
|
||||||
|
|||||||
@@ -217,9 +217,7 @@ class MessagingManagerImpl extends ConversationClientImpl
|
|||||||
public String getMessageBody(MessageId m) throws DbException {
|
public String getMessageBody(MessageId m) throws DbException {
|
||||||
try {
|
try {
|
||||||
// 0: private message body
|
// 0: private message body
|
||||||
BdfList message = clientHelper.getMessageAsList(m);
|
return clientHelper.getMessageAsList(m).getString(0);
|
||||||
if (message == null) throw new DbException();
|
|
||||||
return message.getString(0);
|
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -301,9 +301,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
|||||||
@Override
|
@Override
|
||||||
public String getMessageBody(MessageId m) throws DbException {
|
public String getMessageBody(MessageId m) throws DbException {
|
||||||
try {
|
try {
|
||||||
BdfList body = clientHelper.getMessageAsList(m);
|
return getMessageBody(clientHelper.getMessageAsList(m));
|
||||||
if (body == null) throw new DbException();
|
|
||||||
return getMessageBody(body);
|
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,6 @@ class MessageParserImpl implements MessageParser {
|
|||||||
public InviteMessage getInviteMessage(Transaction txn, MessageId m)
|
public InviteMessage getInviteMessage(Transaction txn, MessageId m)
|
||||||
throws DbException, FormatException {
|
throws DbException, FormatException {
|
||||||
Message message = clientHelper.getMessage(txn, m);
|
Message message = clientHelper.getMessage(txn, m);
|
||||||
if (message == null) throw new DbException();
|
|
||||||
BdfList body = clientHelper.toList(message);
|
BdfList body = clientHelper.toList(message);
|
||||||
return parseInviteMessage(message, body);
|
return parseInviteMessage(message, body);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ abstract class MessageParserImpl<S extends Shareable>
|
|||||||
public InviteMessage<S> getInviteMessage(Transaction txn, MessageId m)
|
public InviteMessage<S> getInviteMessage(Transaction txn, MessageId m)
|
||||||
throws DbException, FormatException {
|
throws DbException, FormatException {
|
||||||
Message message = clientHelper.getMessage(txn, m);
|
Message message = clientHelper.getMessage(txn, m);
|
||||||
if (message == null) throw new DbException();
|
|
||||||
BdfList body = clientHelper.toList(message);
|
BdfList body = clientHelper.toList(message);
|
||||||
return parseInviteMessage(message, body);
|
return parseInviteMessage(message, body);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user