Smack/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrati...

190 lines
8.2 KiB
Java

/**
*
* Copyright 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.ox_im;
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertTrue;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.ox.AbstractOpenPgpIntegrationTest;
import org.jivesoftware.smackx.ox.OpenPgpContact;
import org.jivesoftware.smackx.ox.OpenPgpManager;
import org.jivesoftware.smackx.ox.crypto.PainlessOpenPgpProvider;
import org.jivesoftware.smackx.ox.element.SigncryptElement;
import org.jivesoftware.smackx.ox.store.filebased.FileBasedOpenPgpStore;
import org.jivesoftware.smackx.ox.util.OpenPgpPubSubUtil;
import org.igniterealtime.smack.inttest.SmackIntegrationTest;
import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment;
import org.igniterealtime.smack.inttest.TestNotPossibleException;
import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.pgpainless.decryption_verification.OpenPgpMetadata;
import org.pgpainless.key.OpenPgpV4Fingerprint;
import org.pgpainless.key.protection.UnprotectedKeysProtector;
public class OXInstantMessagingIntegrationTest extends AbstractOpenPgpIntegrationTest {
private static final String sessionId = StringUtils.randomString(10);
private static final File tempDir = org.apache.commons.io.FileUtils.getTempDirectory();
private static final File aliceStorePath = new File(tempDir, "basic_ox_messaging_test_alice_" + sessionId);
private static final File bobStorePath = new File(tempDir, "basic_ox_messaging_test_bob_" + sessionId);
private OpenPgpV4Fingerprint aliceFingerprint = null;
private OpenPgpV4Fingerprint bobFingerprint = null;
private OpenPgpManager aliceOpenPgp;
private OpenPgpManager bobOpenPgp;
/**
* This integration test tests basic OX message exchange.
* In this scenario, Alice and Bob are strangers, as they do not have subscribed to one another.
*
* Alice (conOne) creates keys and publishes them to the server.
* Bob (conTwo) creates keys and publishes them to the server.
*
* Alice then manually fetches Bobs metadata node and all announced keys.
*
* Alice trusts Bobs keys and vice versa (even though Bob does not have copies of Alice' keys yet).
*
* She proceeds to create an OX encrypted message, which is encrypted to Bob and herself and signed by her.
*
* She sends the message.
*
* Bob receives the message, which - due to missing keys - triggers him to update Alice' keys.
*
* After the update Bob proceeds to decrypt and verify the message.
*
* After the test, the keys are deleted from local storage and from PubSub.
*
* @param environment test environment
*
* @throws XMPPException.XMPPErrorException if there was an XMPP error returned.
* @throws InterruptedException if the calling thread was interrupted.
* @throws SmackException.NotConnectedException if the XMPP connection is not connected.
* @throws TestNotPossibleException if the test is not possible due to lacking server support for PEP.
* @throws SmackException.NoResponseException if there was no response from the remote entity.
*/
public OXInstantMessagingIntegrationTest(SmackIntegrationTestEnvironment<?> environment)
throws XMPPException.XMPPErrorException, InterruptedException, SmackException.NotConnectedException,
TestNotPossibleException, SmackException.NoResponseException {
super(environment);
}
@BeforeClass
@AfterClass
public static void deleteStore() throws IOException {
LOGGER.log(Level.INFO, "Deleting storage directories...");
org.apache.commons.io.FileUtils.deleteDirectory(aliceStorePath);
org.apache.commons.io.FileUtils.deleteDirectory(bobStorePath);
}
@SmackIntegrationTest
public void basicInstantMessagingTest()
throws Exception {
LOGGER.log(Level.INFO, aliceStorePath.getAbsolutePath() + " " + bobStorePath.getAbsolutePath());
final SimpleResultSyncPoint bobReceivedMessage = new SimpleResultSyncPoint();
final String body = "Writing integration tests is an annoying task, but it has to be done, so lets do it!!!";
FileBasedOpenPgpStore aliceStore = new FileBasedOpenPgpStore(aliceStorePath);
aliceStore.setKeyRingProtector(new UnprotectedKeysProtector());
FileBasedOpenPgpStore bobStore = new FileBasedOpenPgpStore(bobStorePath);
bobStore.setKeyRingProtector(new UnprotectedKeysProtector());
PainlessOpenPgpProvider aliceProvider = new PainlessOpenPgpProvider(aliceConnection, aliceStore);
PainlessOpenPgpProvider bobProvider = new PainlessOpenPgpProvider(bobConnection, bobStore);
aliceOpenPgp = OpenPgpManager.getInstanceFor(aliceConnection);
bobOpenPgp = OpenPgpManager.getInstanceFor(bobConnection);
OXInstantMessagingManager aliceInstantMessaging = OXInstantMessagingManager.getInstanceFor(aliceConnection);
OXInstantMessagingManager bobInstantMessaging = OXInstantMessagingManager.getInstanceFor(bobConnection);
bobInstantMessaging.addOxMessageListener(new OxMessageListener() {
@Override
public void newIncomingOxMessage(OpenPgpContact contact, Message originalMessage, SigncryptElement decryptedPayload, OpenPgpMetadata metadata) {
if (((Message.Body) decryptedPayload.getExtension(Message.Body.NAMESPACE)).getMessage().equals(body)) {
bobReceivedMessage.signal();
} else {
bobReceivedMessage.signalFailure();
}
}
});
aliceOpenPgp.setOpenPgpProvider(aliceProvider);
bobOpenPgp.setOpenPgpProvider(bobProvider);
aliceFingerprint = aliceOpenPgp.generateAndImportKeyPair(alice);
bobFingerprint = bobOpenPgp.generateAndImportKeyPair(bob);
aliceOpenPgp.announceSupportAndPublish();
bobOpenPgp.announceSupportAndPublish();
OpenPgpContact bobForAlice = aliceOpenPgp.getOpenPgpContact(bob.asEntityBareJidIfPossible());
OpenPgpContact aliceForBob = bobOpenPgp.getOpenPgpContact(alice.asEntityBareJidIfPossible());
bobForAlice.updateKeys(aliceConnection);
assertFalse(bobForAlice.isTrusted(bobFingerprint));
assertFalse(aliceForBob.isTrusted(aliceFingerprint));
bobForAlice.trust(bobFingerprint);
aliceForBob.trust(aliceFingerprint);
assertTrue(bobForAlice.isTrusted(bobFingerprint));
assertTrue(aliceForBob.isTrusted(aliceFingerprint));
aliceInstantMessaging.sendOxMessage(bobForAlice, body);
bobReceivedMessage.waitForResult(timeout);
}
@After
public void deleteKeyMetadata()
throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException,
SmackException.NoResponseException {
OpenPgpPubSubUtil.deletePubkeysListNode(alicePepManager);
OpenPgpPubSubUtil.deletePubkeysListNode(bobPepManager);
if (aliceFingerprint != null) {
OpenPgpPubSubUtil.deletePublicKeyNode(alicePepManager, aliceFingerprint);
}
if (bobFingerprint != null) {
OpenPgpPubSubUtil.deletePublicKeyNode(bobPepManager, bobFingerprint);
}
if (aliceOpenPgp != null) {
aliceOpenPgp.stopMetadataListener();
}
if (bobOpenPgp != null) {
bobOpenPgp.stopMetadataListener();
}
}
}