1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2025-12-09 04:21:08 +01:00

Rewrite integration tests

This commit is contained in:
Paul Schaub 2018-01-09 15:18:28 +01:00
parent 8b8c6e190a
commit f3403571a7
11 changed files with 580 additions and 319 deletions

View file

@ -93,7 +93,7 @@ public final class OmemoManager extends Manager {
private static final Logger LOGGER = Logger.getLogger(OmemoManager.class.getName());
private static final Integer UNKNOWN_DEVICE_ID = -1;
private final Object LOCK = new Object();
final Object LOCK = new Object();
private static final WeakHashMap<XMPPConnection, TreeMap<Integer,OmemoManager>> INSTANCES = new WeakHashMap<>();
private final OmemoService<?, ?, ?, ?, ?, ?, ?, ?, ?> service;
@ -613,18 +613,37 @@ public final class OmemoManager extends Manager {
}
}
/**
* Add an OmemoMessageListener. This listener will be informed about incoming OMEMO messages
* (as well as KeyTransportMessages) and OMEMO encrypted message carbons.
*
* @param listener OmemoMessageListener
*/
public void addOmemoMessageListener(OmemoMessageListener listener) {
omemoMessageListeners.add(listener);
}
/**
* Remove an OmemoMessageListener.
* @param listener OmemoMessageListener
*/
public void removeOmemoMessageListener(OmemoMessageListener listener) {
omemoMessageListeners.remove(listener);
}
/**
* Add an OmemoMucMessageListener. This listener will be informed about incoming OMEMO encrypted MUC messages.
*
* @param listener OmemoMessageListener.
*/
public void addOmemoMucMessageListener(OmemoMucMessageListener listener) {
omemoMucMessageListeners.add(listener);
}
/**
* Remove an OmemoMucMessageListener.
* @param listener OmemoMucMessageListener
*/
public void removeOmemoMucMessageListener(OmemoMucMessageListener listener) {
omemoMucMessageListeners.remove(listener);
}
@ -787,25 +806,12 @@ public final class OmemoManager extends Manager {
}
}
/**
* Notify all registered OmemoMessageListeners about a received OMEMO KeyTransportMessage.
*
* @param stanza original stanza.
* @param decryptedKeyTransportMessage decrypted KeyTransportMessage.
*/
void notifyOmemoKeyTransportMessageReceived(Stanza stanza, OmemoMessage.Received decryptedKeyTransportMessage)
{
for (OmemoMessageListener l : omemoMessageListeners) {
l.onOmemoKeyTransportReceived(stanza, decryptedKeyTransportMessage);
}
}
/**
* Notify all registered OmemoMucMessageListeners of an incoming OmemoMessageElement in a MUC.
*
* @param muc MultiUserChat the message was received in.
* @param stanza Original Stanza.
* @param decryptedMessage Decryped OmemoMessage.
* @param decryptedMessage Decrypted OmemoMessage.
*/
void notifyOmemoMucMessageReceived(MultiUserChat muc,
Stanza stanza,
@ -817,18 +823,21 @@ public final class OmemoManager extends Manager {
}
/**
* Notify registered OmemoMucMessageReceived listeners about KeyTransportMessages sent in a MUC.
* Notify all registered OmemoMessageListeners of an incoming OMEMO encrypted Carbon Copy.
* Remember: If you want to receive OMEMO encrypted carbon copies, you have to enable carbons using
* {@link CarbonManager#enableCarbons()}.
*
* @param muc MultiUserChat in which the message was sent
* @param stanza original stanza
* @param decryptedKeyTransportMessage decrypted OMEMO KeyTransportElement
* @param direction direction of the carbon copy
* @param carbonCopy carbon copy itself
* @param wrappingMessage wrapping message
* @param decryptedCarbonCopy decrypted carbon copy OMEMO element
*/
void notifyOmemoMucKeyTransportMessageReceived(MultiUserChat muc,
Stanza stanza,
OmemoMessage.Received decryptedKeyTransportMessage)
{
for (OmemoMucMessageListener l : omemoMucMessageListeners) {
l.onOmemoKeyTransportReceived(muc, stanza, decryptedKeyTransportMessage);
void notifyOmemoCarbonCopyReceived(CarbonExtension.Direction direction,
Message carbonCopy,
Message wrappingMessage,
OmemoMessage.Received decryptedCarbonCopy) {
for (OmemoMessageListener l : omemoMessageListeners) {
l.onOmemoCarbonCopyReceived(direction, carbonCopy, wrappingMessage, decryptedCarbonCopy);
}
}

View file

@ -31,6 +31,8 @@ import org.jivesoftware.smackx.omemo.element.OmemoElement;
import org.jivesoftware.smackx.omemo.internal.OmemoDevice;
import org.jivesoftware.smackx.omemo.trust.OmemoFingerprint;
import org.jxmpp.jid.Jid;
public class OmemoMessage {
private final OmemoElement element;
@ -42,43 +44,91 @@ public class OmemoMessage {
this.iv = iv;
}
/**
* Return the original OmemoElement (&lt;encrypted/&gt;).
*
* @return omemoElement
*/
public OmemoElement getElement() {
return element;
}
/**
* Return the messageKey (or transported key in case of a KeyTransportMessage).
*
* @return key
*/
public byte[] getKey() {
return messageKey.clone();
}
/**
* Return the initialization vector belonging to the key.
* @return initialization vector
*/
public byte[] getIv() {
return iv.clone();
}
/**
* Outgoing OMEMO message.
*/
public static class Sent extends OmemoMessage {
private final ArrayList<OmemoDevice> intendedDevices = new ArrayList<>();
private final HashMap<OmemoDevice, Throwable> skippedDevices = new HashMap<>();
/**
* Create a new outgoing OMEMO message.
* @param element OmemoElement
* @param key messageKey (or transported key)
* @param iv initialization vector belonging to key
* @param intendedDevices devices the client intended to encrypt the message for
* @param skippedDevices devices which were skipped during encryption process because encryption
* failed for some reason
*/
Sent(OmemoElement element, byte[] key, byte[] iv, List<OmemoDevice> intendedDevices, HashMap<OmemoDevice, Throwable> skippedDevices) {
super(element, key, iv);
this.intendedDevices.addAll(intendedDevices);
this.skippedDevices.putAll(skippedDevices);
}
public ArrayList<OmemoDevice> getIntendedDevices() {
/**
* Return a list of all devices the sender originally intended to encrypt the message for.
* @return list of intended recipients.
*/
public List<OmemoDevice> getIntendedDevices() {
return intendedDevices;
}
/**
* Return a map of all skipped recipients and the reasons for skipping.
* @return map of skipped recipients and reasons for that.
*/
public HashMap<OmemoDevice, Throwable> getSkippedDevices() {
return skippedDevices;
}
/**
* Determine, if some recipients were skipped during encryption.
* @return true if recipients were skipped.
*/
public boolean isMissingRecipients() {
return !getSkippedDevices().isEmpty();
}
public Message asMessage() {
/**
* Return the OmemoElement wrapped in a Message ready to be sent.
* The message is addressed to recipient, contains the OmemoElement
* as well as an optional clear text hint as body, a MAM storage hint
* and an EME hint about OMEMO encryption.
*
* @param recipient recipient for the to-field of the message.
* @return Message
*/
public Message asMessage(Jid recipient) {
Message messageStanza = new Message();
messageStanza.setTo(recipient);
messageStanza.addExtension(getElement());
if (OmemoConfiguration.getAddOmemoHintBody()) {
@ -92,54 +142,72 @@ public class OmemoMessage {
}
}
/**
* Incoming OMEMO message.
*/
public static class Received extends OmemoMessage {
private final String message;
private final OmemoFingerprint sendersFingerprint;
private final OmemoDevice senderDevice;
private final CARBON carbon;
private final boolean preKeyMessage;
Received(OmemoElement element, byte[] key, byte[] iv, String message, OmemoFingerprint sendersFingerprint, OmemoDevice senderDevice, CARBON carbon, boolean preKeyMessage) {
/**
* Create a new incoming OMEMO message.
* @param element original OmemoElement
* @param key message key (or transported key)
* @param iv respective initialization vector
* @param body decrypted body
* @param sendersFingerprint OmemoFingerprint of the senders identityKey
* @param senderDevice OmemoDevice of the sender
* @param preKeyMessage if this was a preKeyMessage or not
*/
Received(OmemoElement element, byte[] key, byte[] iv, String body, OmemoFingerprint sendersFingerprint, OmemoDevice senderDevice, boolean preKeyMessage) {
super(element, key, iv);
this.message = message;
this.message = body;
this.sendersFingerprint = sendersFingerprint;
this.senderDevice = senderDevice;
this.carbon = carbon;
this.preKeyMessage = preKeyMessage;
}
public String getMessage() {
/**
* Return the decrypted body of the message.
* @return decrypted body
*/
public String getBody() {
return message;
}
/**
* Return the fingerprint of the messages sender device.
* @return fingerprint of sender
*/
public OmemoFingerprint getSendersFingerprint() {
return sendersFingerprint;
}
/**
* Return the OmemoDevice which sent the message.
* @return senderDevice
*/
public OmemoDevice getSenderDevice() {
return senderDevice;
}
/**
* Return the carbon type.
*
* @return carbon type
* Return true, if this message was sent as a preKeyMessage.
* @return preKeyMessage or not
*/
public CARBON getCarbon() {
return carbon;
}
boolean isPreKeyMessage() {
return preKeyMessage;
}
}
/**
* Types of Carbon Messages.
*/
public enum CARBON {
NONE, //No carbon
SENT, //Sent carbon
RECV //Received Carbon
/**
* Return true, if the message was a KeyTransportMessage.
* A KeyTransportMessage is a OmemoMessage without a payload.
* @return keyTransportMessage?
*/
public boolean isKeyTransportMessage() {
return message == null;
}
}
}

View file

@ -435,8 +435,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
*/
private OmemoMessage.Received decryptMessage(OmemoManager.LoggedInOmemoManager managerGuard,
BareJid senderJid,
OmemoElement omemoElement,
OmemoMessage.CARBON carbon)
OmemoElement omemoElement)
throws CorruptedOmemoKeyException, CryptoFailedException, NoRawSessionException
{
OmemoManager manager = managerGuard.get();
@ -459,12 +458,12 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
String plaintext = OmemoRatchet.decryptMessageElement(omemoElement, cipherAndAuthTag);
return new OmemoMessage.Received(omemoElement, cipherAndAuthTag.getKey(), cipherAndAuthTag.getIv(),
plaintext, senderFingerprint, senderDevice, carbon, cipherAndAuthTag.wasPreKeyEncrypted());
plaintext, senderFingerprint, senderDevice, cipherAndAuthTag.wasPreKeyEncrypted());
} else {
// KeyTransportMessages don't require decryption of the payload.
return new OmemoMessage.Received(omemoElement, cipherAndAuthTag.getKey(), cipherAndAuthTag.getIv(),
null, senderFingerprint, senderDevice, carbon, cipherAndAuthTag.wasPreKeyEncrypted());
null, senderFingerprint, senderDevice, cipherAndAuthTag.wasPreKeyEncrypted());
}
}
@ -1027,7 +1026,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
* @param userDevice our OmemoDevice
* @param devices collection of OmemoDevices
*/
private static void removeOurDevice(OmemoDevice userDevice, Collection<OmemoDevice> devices) {
static void removeOurDevice(OmemoDevice userDevice, Collection<OmemoDevice> devices) {
if (devices.contains(userDevice)) {
devices.remove(userDevice);
}
@ -1074,67 +1073,138 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
};
@Override
public void onOmemoCarbonCopyReceived(CarbonExtension.Direction direction, Message carbonCopy, Message wrappingMessage, OmemoManager.LoggedInOmemoManager omemoManager) {
// TODO: implement
public void onOmemoCarbonCopyReceived(CarbonExtension.Direction direction,
Message carbonCopy,
Message wrappingMessage,
OmemoManager.LoggedInOmemoManager managerGuard) {
OmemoManager manager = managerGuard.get();
// Avoid the ratchet being manipulated and the bundle being published multiple times simultaneously
synchronized (manager) {
OmemoDevice userDevice = manager.getOwnDevice();
OmemoElement element = carbonCopy.getExtension(OmemoElement.NAME_ENCRYPTED, OmemoElement_VAxolotl.NAMESPACE);
if (element == null) {
return;
}
OmemoMessage.Received decrypted;
BareJid sender = carbonCopy.getFrom().asBareJid();
try {
decrypted = decryptMessage(managerGuard, sender, element);
manager.notifyOmemoCarbonCopyReceived(direction, carbonCopy, wrappingMessage, decrypted);
if (decrypted.isPreKeyMessage() && OmemoConfiguration.getCompleteSessionWithEmptyMessage()) {
LOGGER.log(Level.FINE, "Received a preKeyMessage in a carbon copy from " + decrypted.getSenderDevice() + ".\n" +
"Complete the session by sending an empty response message.");
try {
sendRatchetUpdate(managerGuard, decrypted.getSenderDevice());
} catch (CannotEstablishOmemoSessionException e) {
throw new AssertionError("Since we successfully received a message, we MUST be able to " +
"establish a session. " + e);
} catch (NoSuchAlgorithmException | InterruptedException | SmackException.NotConnectedException | SmackException.NoResponseException e) {
LOGGER.log(Level.WARNING, "Cannot send a ratchet update message.", e);
}
}
} catch (NoRawSessionException e) {
OmemoDevice device = e.getDeviceWithoutSession();
LOGGER.log(Level.WARNING, "No raw session found for contact " + device + ". ", e);
if (OmemoConfiguration.getRepairBrokenSessionsWithPreKeyMessages()) {
repairBrokenSessionWithPreKeyMessage(managerGuard, device);
}
} catch (CorruptedOmemoKeyException | CryptoFailedException e) {
LOGGER.log(Level.WARNING, "Could not decrypt incoming carbon copy: ", e);
}
// Upload fresh bundle.
if (getOmemoStoreBackend().loadOmemoPreKeys(userDevice).size() < OmemoConstants.PRE_KEY_COUNT_PER_BUNDLE) {
LOGGER.log(Level.FINE, "We used up a preKey. Upload a fresh bundle.");
try {
getOmemoStoreBackend().replenishKeys(userDevice);
OmemoBundleElement bundleElement = getOmemoStoreBackend().packOmemoBundle(userDevice);
publishBundle(manager.getConnection(), userDevice, bundleElement);
} catch (CorruptedOmemoKeyException | InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) {
LOGGER.log(Level.WARNING, "Could not republish replenished bundle.", e);
}
}
}
}
@Override
public void onOmemoMessageStanzaReceived(Stanza stanza, OmemoManager.LoggedInOmemoManager managerGuard) {
OmemoManager manager = managerGuard.get();
OmemoElement element = stanza.getExtension(OmemoElement.NAME_ENCRYPTED, OmemoElement_VAxolotl.NAMESPACE);
if (element == null) {
return;
}
// Avoid the ratchet being manipulated and the bundle being published multiple times simultaneously
synchronized (manager.LOCK) {
OmemoDevice userDevice = manager.getOwnDevice();
OmemoElement element = stanza.getExtension(OmemoElement.NAME_ENCRYPTED, OmemoElement_VAxolotl.NAMESPACE);
if (element == null) {
return;
}
OmemoMessage.Received decrypted;
BareJid sender;
OmemoMessage.Received decrypted;
BareJid sender;
try {
MultiUserChat muc = getMuc(manager.getConnection(), stanza.getFrom());
if (muc != null) {
Occupant occupant = muc.getOccupant(stanza.getFrom().asEntityFullJidIfPossible());
Jid occupantJid = occupant.getJid();
try {
MultiUserChat muc = getMuc(manager.getConnection(), stanza.getFrom());
if (muc != null) {
Occupant occupant = muc.getOccupant(stanza.getFrom().asEntityFullJidIfPossible());
Jid occupantJid = occupant.getJid();
if (occupantJid == null) {
LOGGER.log(Level.WARNING, "MUC message received, but there is no way to retrieve the senders Jid. " +
stanza.getFrom());
return;
}
if (occupantJid == null) {
LOGGER.log(Level.WARNING, "MUC message received, but there is no way to retrieve the senders Jid. " +
stanza.getFrom());
return;
}
sender = occupantJid.asBareJid();
sender = occupantJid.asBareJid();
// try is for this
decrypted = decryptMessage(managerGuard, sender, element, OmemoMessage.CARBON.NONE);
if (element.isMessageElement()) {
// try is for this
decrypted = decryptMessage(managerGuard, sender, element);
manager.notifyOmemoMucMessageReceived(muc, stanza, decrypted);
} else {
manager.notifyOmemoMucKeyTransportMessageReceived(muc, stanza, decrypted);
}
} else {
sender = stanza.getFrom().asBareJid();
sender = stanza.getFrom().asBareJid();
// and this
decrypted = decryptMessage(managerGuard, sender, element, OmemoMessage.CARBON.NONE);
if (element.isMessageElement()) {
// and this
decrypted = decryptMessage(managerGuard, sender, element);
manager.notifyOmemoMessageReceived(stanza, decrypted);
} else {
manager.notifyOmemoKeyTransportMessageReceived(stanza, decrypted);
}
if (decrypted.isPreKeyMessage() && OmemoConfiguration.getCompleteSessionWithEmptyMessage()) {
LOGGER.log(Level.FINE, "Received a preKeyMessage from " + decrypted.getSenderDevice() + ".\n" +
"Complete the session by sending an empty response message.");
try {
sendRatchetUpdate(managerGuard, decrypted.getSenderDevice());
} catch (CannotEstablishOmemoSessionException e) {
throw new AssertionError("Since we successfully received a message, we MUST be able to " +
"establish a session. " + e);
} catch (NoSuchAlgorithmException | InterruptedException | SmackException.NotConnectedException | SmackException.NoResponseException e) {
LOGGER.log(Level.WARNING, "Cannot send a ratchet update message.", e);
}
}
} catch (NoRawSessionException e) {
OmemoDevice device = e.getDeviceWithoutSession();
LOGGER.log(Level.WARNING, "No raw session found for contact " + device + ". ", e);
if (OmemoConfiguration.getRepairBrokenSessionsWithPreKeyMessages()) {
repairBrokenSessionWithPreKeyMessage(managerGuard, device);
}
} catch (CorruptedOmemoKeyException | CryptoFailedException e) {
LOGGER.log(Level.WARNING, "Could not decrypt incoming message: ", e);
}
// Upload fresh bundle.
if (getOmemoStoreBackend().loadOmemoPreKeys(userDevice).size() < OmemoConstants.PRE_KEY_COUNT_PER_BUNDLE) {
LOGGER.log(Level.FINE, "We used up a preKey. Upload a fresh bundle.");
try {
getOmemoStoreBackend().replenishKeys(userDevice);
OmemoBundleElement bundleElement = getOmemoStoreBackend().packOmemoBundle(userDevice);
publishBundle(manager.getConnection(), userDevice, bundleElement);
} catch (CorruptedOmemoKeyException | InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) {
LOGGER.log(Level.WARNING, "Could not republish replenished bundle.", e);
}
}
}
catch (NoRawSessionException e) {
OmemoDevice device = e.getDeviceWithoutSession();
LOGGER.log(Level.WARNING, "No raw session found for contact " + device + ". ", e);
if (OmemoConfiguration.getRepairBrokenSessionsWithPreKeyMessages()) {
repairBrokenSessionWithPreKeyMessage(managerGuard, device);
}
}
catch (CorruptedOmemoKeyException | CryptoFailedException e) {
LOGGER.log(Level.WARNING, "Could not decrypt incoming message: ", e);
}
}
/**
@ -1152,11 +1222,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
try {
// Create fresh session and send new preKeyMessage.
buildFreshSessionWithDevice(manager.getConnection(), manager.getOwnDevice(), brokenDevice);
OmemoElement ratchetUpdate = createRatchetUpdateElement(managerGuard, brokenDevice);
Message m = new Message();
m.setTo(brokenDevice.getJid());
m.addExtension(ratchetUpdate);
manager.getConnection().sendStanza(m);
sendRatchetUpdate(managerGuard, brokenDevice);
} catch (CannotEstablishOmemoSessionException | CorruptedOmemoKeyException e) {
LOGGER.log(Level.WARNING, "Unable to repair session with " + brokenDevice, e);
@ -1167,6 +1233,31 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
}
}
/**
* Send an empty OMEMO message to contactsDevice in order to forward the ratchet.
* @param managerGuard
* @param contactsDevice
* @throws CorruptedOmemoKeyException if our or their OMEMO key is corrupted.
* @throws InterruptedException
* @throws SmackException.NoResponseException
* @throws NoSuchAlgorithmException if AES encryption fails
* @throws SmackException.NotConnectedException
* @throws CryptoFailedException if encryption fails (should not happen though, but who knows...)
* @throws CannotEstablishOmemoSessionException if we cannot establish a session with contactsDevice.
*/
private void sendRatchetUpdate(OmemoManager.LoggedInOmemoManager managerGuard, OmemoDevice contactsDevice)
throws CorruptedOmemoKeyException, InterruptedException, SmackException.NoResponseException,
NoSuchAlgorithmException, SmackException.NotConnectedException, CryptoFailedException,
CannotEstablishOmemoSessionException
{
OmemoManager manager = managerGuard.get();
OmemoElement ratchetUpdate = createRatchetUpdateElement(managerGuard, contactsDevice);
Message m = new Message();
m.setTo(contactsDevice.getJid());
m.addExtension(ratchetUpdate);
manager.getConnection().sendStanza(m);
}
/**
* Return the joined MUC with EntityBareJid jid, or null if its not a room and/or not joined.
* @param connection xmpp connection

View file

@ -16,7 +16,9 @@
*/
package org.jivesoftware.smackx.omemo.listener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smackx.carbons.packet.CarbonExtension;
import org.jivesoftware.smackx.omemo.OmemoMessage;
/**
@ -33,11 +35,8 @@ public interface OmemoMessageListener {
*/
void onOmemoMessageReceived(Stanza stanza, OmemoMessage.Received decryptedMessage);
/**
* Gets called, whenever an OmemoElement without a body (an OmemoKeyTransportElement) is received.
*
* @param stanza received (encrypted) stanza.
* @param decryptedKeyTransportMessage decrypted OMEMO key transport message.
*/
void onOmemoKeyTransportReceived(Stanza stanza, OmemoMessage.Received decryptedKeyTransportMessage);
void onOmemoCarbonCopyReceived(CarbonExtension.Direction direction,
Message carbonCopy,
Message wrappingMessage,
OmemoMessage.Received decryptedCarbonCopy);
}

View file

@ -33,13 +33,4 @@ public interface OmemoMucMessageListener {
* @param decryptedOmemoMessage decrypted Omemo message
*/
void onOmemoMucMessageReceived(MultiUserChat muc, Stanza stanza, OmemoMessage.Received decryptedOmemoMessage);
/**
* Gets called, whenever an OmemoElement without a body (an OmemoKeyTransportElement) is received.
*
* @param muc MultiUserChat the message was sent in
* @param stanza original stanza
* @param decryptedKeyTransportElement decrypted KeyTransportMessage
*/
void onOmemoKeyTransportReceived(MultiUserChat muc, Stanza stanza, OmemoMessage.Received decryptedKeyTransportElement);
}

View file

@ -17,7 +17,9 @@
package org.jivesoftware.smackx.omemo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
@ -40,18 +42,6 @@ public class OmemoConfigurationTest {
assertEquals("FileBasedOmemoStoreDefaultPath must equal the one we set.", storePath.getAbsolutePath(),
OmemoConfiguration.getFileBasedOmemoStoreDefaultPath().getAbsolutePath());
// EME
OmemoConfiguration.setAddEmeEncryptionHint(false);
assertEquals(false, OmemoConfiguration.getAddEmeEncryptionHint());
OmemoConfiguration.setAddEmeEncryptionHint(true);
assertEquals(true, OmemoConfiguration.getAddEmeEncryptionHint());
// MAM
OmemoConfiguration.setAddMAMStorageProcessingHint(false);
assertEquals(false, OmemoConfiguration.getAddMAMStorageProcessingHint());
OmemoConfiguration.setAddMAMStorageProcessingHint(true);
assertEquals(true, OmemoConfiguration.getAddMAMStorageProcessingHint());
// Body hint
OmemoConfiguration.setAddOmemoHintBody(false);
assertEquals(false, OmemoConfiguration.getAddOmemoHintBody());
@ -107,5 +97,17 @@ public class OmemoConfigurationTest {
} catch (IllegalArgumentException e) {
// Expected
}
// Repair broken sessions
OmemoConfiguration.setRepairBrokenSessionsWithPrekeyMessages(false);
assertFalse(OmemoConfiguration.getRepairBrokenSessionsWithPreKeyMessages());
OmemoConfiguration.setRepairBrokenSessionsWithPrekeyMessages(true);
assertTrue(OmemoConfiguration.getRepairBrokenSessionsWithPreKeyMessages());
// Complete fresh sessions
OmemoConfiguration.setCompleteSessionWithEmptyMessage(false);
assertFalse(OmemoConfiguration.getCompleteSessionWithEmptyMessage());
OmemoConfiguration.setCompleteSessionWithEmptyMessage(true);
assertTrue(OmemoConfiguration.getCompleteSessionWithEmptyMessage());
}
}

View file

@ -20,6 +20,7 @@ import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertTrue;
import java.util.Date;
import java.util.HashSet;
import org.jivesoftware.smack.test.util.SmackTestSuite;
import org.jivesoftware.smackx.omemo.internal.OmemoDevice;
@ -34,6 +35,16 @@ public class OmemoServiceTest extends SmackTestSuite {
private static final int IGNORE_STALE = OmemoConfiguration.getIgnoreStaleDevicesAfterHours();
private static final int DELETE_STALE = OmemoConfiguration.getDeleteStaleDevicesAfterHours();
@Test(expected = IllegalStateException.class)
public void getInstanceFailsWhenNullTest() {
OmemoService.getInstance();
}
@Test
public void isServiceRegisteredTest() {
assertFalse(OmemoService.isServiceRegistered());
}
/**
* Test correct functionality of isStale method.
* @throws XmppStringprepException
@ -57,5 +68,24 @@ public class OmemoServiceTest extends SmackTestSuite {
// Own device is never stale, no matter how old
assertFalse(OmemoService.isStale(user, user, deleteMe, DELETE_STALE));
// Always return false if date is null.
assertFalse(OmemoService.isStale(user, other, null, DELETE_STALE));
}
@Test
public void removeOurDeviceTest() throws XmppStringprepException {
OmemoDevice a = new OmemoDevice(JidCreate.bareFrom("a@b.c"), 123);
OmemoDevice b = new OmemoDevice(JidCreate.bareFrom("a@b.c"), 124);
HashSet<OmemoDevice> devices = new HashSet<>();
devices.add(a); devices.add(b);
assertTrue(devices.contains(a));
assertTrue(devices.contains(b));
OmemoService.removeOurDevice(a, devices);
assertFalse(devices.contains(a));
assertTrue(devices.contains(b));
}
}