From 4b3f757ed9dfc66835eb6991f17e0dfef9c4c369 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 15 Aug 2018 18:07:42 +0200 Subject: [PATCH] Add a PEP PubSubManager to PEPManager --- .../jivesoftware/smackx/pep/PEPManager.java | 8 +++++ .../smackx/pubsub/PubSubManager.java | 35 +++++++++++++------ .../ox/AbstractOpenPgpIntegrationTest.java | 14 ++++++-- .../ox/OXSecretKeyBackupIntegrationTest.java | 2 +- .../OXInstantMessagingIntegrationTest.java | 8 ++--- .../smackx/ox/OpenPgpManager.java | 9 +++-- .../smackx/ox/util/OpenPgpPubSubUtil.java | 35 ++++++++++--------- 7 files changed, 72 insertions(+), 39 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/PEPManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/PEPManager.java index cd9ce58d2..8516ef455 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/PEPManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/PEPManager.java @@ -89,6 +89,8 @@ public final class PEPManager extends Manager { private final AsyncButOrdered asyncButOrdered = new AsyncButOrdered<>(); + private final PubSubManager pepPubSubManager; + /** * Creates a new PEP exchange manager. * @@ -116,6 +118,12 @@ public final class PEPManager extends Manager { }; // TODO Add filter to check if from supports PubSub as per xep163 2 2.4 connection.addSyncStanzaListener(packetListener, FROM_BARE_JID_WITH_EVENT_EXTENSION_FILTER); + + pepPubSubManager = PubSubManager.getInstance(connection, null); + } + + public PubSubManager getPepPubSubManager() { + return pepPubSubManager; } /** diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java index 74e705030..9a248d2b5 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java @@ -114,23 +114,36 @@ public final class PubSubManager extends Manager { } /** - * Get the PubSub manager for the given connection and PubSub service. + * Get the PubSub manager for the given connection and PubSub service. Use null as argument for + * pubSubService to retrieve a PubSubManager for the users PEP service. * * @param connection the XMPP connection. - * @param pubSubService the PubSub service. + * @param pubSubService the PubSub service, may be null. * @return a PubSub manager for the connection and service. */ - public static synchronized PubSubManager getInstance(XMPPConnection connection, BareJid pubSubService) { - Map managers = INSTANCES.get(connection); - if (managers == null) { - managers = new HashMap<>(); - INSTANCES.put(connection, managers); + public static PubSubManager getInstance(XMPPConnection connection, BareJid pubSubService) { + if (pubSubService != null && connection.isAuthenticated() && connection.getUser().asBareJid().equals(pubSubService)) { + // PEP service. + pubSubService = null; } - PubSubManager pubSubManager = managers.get(pubSubService); - if (pubSubManager == null) { - pubSubManager = new PubSubManager(connection, pubSubService); - managers.put(pubSubService, pubSubManager); + + PubSubManager pubSubManager; + Map managers; + synchronized (INSTANCES) { + managers = INSTANCES.get(connection); + if (managers == null) { + managers = new HashMap<>(); + INSTANCES.put(connection, managers); + } } + synchronized (managers) { + pubSubManager = managers.get(pubSubService); + if (pubSubManager == null) { + pubSubManager = new PubSubManager(connection, pubSubService); + managers.put(pubSubService, pubSubManager); + } + } + return pubSubManager; } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/AbstractOpenPgpIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/AbstractOpenPgpIntegrationTest.java index 7663327ed..06258fb7c 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/AbstractOpenPgpIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/AbstractOpenPgpIntegrationTest.java @@ -37,6 +37,10 @@ public abstract class AbstractOpenPgpIntegrationTest extends AbstractSmackIntegr protected final BareJid bob; protected final BareJid chloe; + protected final PEPManager alicePepManager; + protected final PEPManager bobPepManager; + protected final PEPManager chloePepManager; + protected AbstractOpenPgpIntegrationTest(SmackIntegrationTestEnvironment environment) throws XMPPException.XMPPErrorException, TestNotPossibleException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException { @@ -54,9 +58,13 @@ public abstract class AbstractOpenPgpIntegrationTest extends AbstractSmackIntegr this.bob = bobConnection.getUser().asBareJid(); this.chloe = chloeConnection.getUser().asBareJid(); - OpenPgpPubSubUtil.deletePubkeysListNode(aliceConnection); - OpenPgpPubSubUtil.deletePubkeysListNode(bobConnection); - OpenPgpPubSubUtil.deletePubkeysListNode(chloeConnection); + this.alicePepManager = PEPManager.getInstanceFor(aliceConnection); + this.bobPepManager = PEPManager.getInstanceFor(bobConnection); + this.chloePepManager = PEPManager.getInstanceFor(chloeConnection); + + OpenPgpPubSubUtil.deletePubkeysListNode(alicePepManager); + OpenPgpPubSubUtil.deletePubkeysListNode(bobPepManager); + OpenPgpPubSubUtil.deletePubkeysListNode(chloePepManager); } private static void throwIfPubSubNotSupported(XMPPConnection connection) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/OXSecretKeyBackupIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/OXSecretKeyBackupIntegrationTest.java index 9efd636df..d3312f638 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/OXSecretKeyBackupIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/OXSecretKeyBackupIntegrationTest.java @@ -119,7 +119,7 @@ public class OXSecretKeyBackupIntegrationTest extends AbstractOpenPgpIntegration public void cleanUp() throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException { - OpenPgpPubSubUtil.deleteSecretKeyNode(aliceConnection); + OpenPgpPubSubUtil.deleteSecretKeyNode(alicePepManager); if (openPgpManager != null) { openPgpManager.stopMetadataListener(); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrationTest.java index d105c5288..a2be441ef 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrationTest.java @@ -167,14 +167,14 @@ public class OXInstantMessagingIntegrationTest extends AbstractOpenPgpIntegratio public void deleteKeyMetadata() throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException { - OpenPgpPubSubUtil.deletePubkeysListNode(aliceConnection); - OpenPgpPubSubUtil.deletePubkeysListNode(bobConnection); + OpenPgpPubSubUtil.deletePubkeysListNode(alicePepManager); + OpenPgpPubSubUtil.deletePubkeysListNode(bobPepManager); if (aliceFingerprint != null) { - OpenPgpPubSubUtil.deletePublicKeyNode(aliceConnection, aliceFingerprint); + OpenPgpPubSubUtil.deletePublicKeyNode(alicePepManager, aliceFingerprint); } if (bobFingerprint != null) { - OpenPgpPubSubUtil.deletePublicKeyNode(bobConnection, bobFingerprint); + OpenPgpPubSubUtil.deletePublicKeyNode(bobPepManager, bobFingerprint); } if (aliceOpenPgp != null) { diff --git a/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/OpenPgpManager.java b/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/OpenPgpManager.java index 594c8377f..735ef1fe4 100644 --- a/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/OpenPgpManager.java +++ b/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/OpenPgpManager.java @@ -166,6 +166,8 @@ public final class OpenPgpManager extends Manager { */ private OpenPgpProvider provider; + private final PEPManager pepManager; + private final Set signcryptElementReceivedListeners = new HashSet<>(); private final Set signElementReceivedListeners = new HashSet<>(); private final Set cryptElementReceivedListeners = new HashSet<>(); @@ -178,6 +180,7 @@ public final class OpenPgpManager extends Manager { private OpenPgpManager(XMPPConnection connection) { super(connection); ChatManager.getInstanceFor(connection).addIncomingListener(incomingOpenPgpMessageListener); + pepManager = PEPManager.getInstanceFor(connection); } /** @@ -272,7 +275,7 @@ public final class OpenPgpManager extends Manager { } // publish it - publishPublicKey(connection(), pubkeyElement, primaryFingerprint); + publishPublicKey(pepManager, pubkeyElement, primaryFingerprint); // Subscribe to public key changes PEPManager.getInstanceFor(connection()).addPEPListener(metadataListener); @@ -439,7 +442,7 @@ public final class OpenPgpManager extends Manager { throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, SmackException.NotLoggedInException { throwIfNotAuthenticated(); - OpenPgpPubSubUtil.deleteSecretKeyNode(connection()); + OpenPgpPubSubUtil.deleteSecretKeyNode(pepManager); } /** @@ -467,7 +470,7 @@ public final class OpenPgpManager extends Manager { NoBackupFoundException, PGPException { throwIfNoProviderSet(); throwIfNotAuthenticated(); - SecretkeyElement backup = OpenPgpPubSubUtil.fetchSecretKey(connection()); + SecretkeyElement backup = OpenPgpPubSubUtil.fetchSecretKey(pepManager); if (backup == null) { throw new NoBackupFoundException(); } diff --git a/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/util/OpenPgpPubSubUtil.java b/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/util/OpenPgpPubSubUtil.java index 2cb53c8d3..e561d567f 100644 --- a/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/util/OpenPgpPubSubUtil.java +++ b/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/util/OpenPgpPubSubUtil.java @@ -34,6 +34,7 @@ import org.jivesoftware.smackx.ox.OpenPgpManager; import org.jivesoftware.smackx.ox.element.PubkeyElement; import org.jivesoftware.smackx.ox.element.PublicKeysListElement; import org.jivesoftware.smackx.ox.element.SecretkeyElement; +import org.jivesoftware.smackx.pep.PEPManager; import org.jivesoftware.smackx.pubsub.AccessModel; import org.jivesoftware.smackx.pubsub.ConfigureForm; import org.jivesoftware.smackx.pubsub.Item; @@ -111,7 +112,7 @@ public class OpenPgpPubSubUtil { * * @see XEP-0373 §4.1 * - * @param connection XMPP connection + * @param pepManager The PEP manager. * @param pubkeyElement {@link PubkeyElement} containing the public key * @param fingerprint fingerprint of the public key * @@ -122,12 +123,12 @@ public class OpenPgpPubSubUtil { * @throws SmackException.NotConnectedException if we are not connected. * @throws SmackException.NoResponseException if the server doesn't respond. */ - public static void publishPublicKey(XMPPConnection connection, PubkeyElement pubkeyElement, OpenPgpV4Fingerprint fingerprint) + public static void publishPublicKey(PEPManager pepManager, PubkeyElement pubkeyElement, OpenPgpV4Fingerprint fingerprint) throws InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException { String keyNodeName = PEP_NODE_PUBLIC_KEY(fingerprint); - PubSubManager pm = PubSubManager.getInstance(connection, connection.getUser().asBareJid()); + PubSubManager pm = pepManager.getPepPubSubManager(); // Check if key available at data node // If not, publish key to data node @@ -179,7 +180,7 @@ public class OpenPgpPubSubUtil { public static PublicKeysListElement fetchPubkeysList(XMPPConnection connection) throws InterruptedException, XMPPException.XMPPErrorException, PubSubException.NotAPubSubNodeException, PubSubException.NotALeafNodeException, SmackException.NotConnectedException, SmackException.NoResponseException { - return fetchPubkeysList(connection, connection.getUser().asBareJid()); + return fetchPubkeysList(connection, null); } @@ -218,7 +219,7 @@ public class OpenPgpPubSubUtil { /** * Delete our metadata node. * - * @param connection XMPP connection + * @param pepManager The PEP manager. * * @throws XMPPException.XMPPErrorException in case of an XMPP protocol error. * @throws SmackException.NotConnectedException if we are not connected. @@ -226,17 +227,17 @@ public class OpenPgpPubSubUtil { * @throws SmackException.NoResponseException if the server doesn't respond. * @return true if the node existed and was deleted, false if the node did not exist. */ - public static boolean deletePubkeysListNode(XMPPConnection connection) + public static boolean deletePubkeysListNode(PEPManager pepManager) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException { - PubSubManager pm = PubSubManager.getInstance(connection, connection.getUser().asBareJid()); + PubSubManager pm = pepManager.getPepPubSubManager(); return pm.deleteNode(PEP_NODE_PUBLIC_KEYS); } /** * Delete the public key node of the key with fingerprint {@code fingerprint}. * - * @param connection XMPP connection + * @param pepManager The PEP manager. * @param fingerprint fingerprint of the key we want to delete * * @throws XMPPException.XMPPErrorException in case of an XMPP protocol error. @@ -245,10 +246,10 @@ public class OpenPgpPubSubUtil { * @throws SmackException.NoResponseException if the server doesn't respond. * @return true if the node existed and was deleted, false if the node did not exist. */ - public static boolean deletePublicKeyNode(XMPPConnection connection, OpenPgpV4Fingerprint fingerprint) + public static boolean deletePublicKeyNode(PEPManager pepManager, OpenPgpV4Fingerprint fingerprint) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException { - PubSubManager pm = PubSubManager.getInstance(connection, connection.getUser().asBareJid()); + PubSubManager pm = pepManager.getPepPubSubManager(); return pm.deleteNode(PEP_NODE_PUBLIC_KEY(fingerprint)); } @@ -345,7 +346,7 @@ public class OpenPgpPubSubUtil { if (!OpenPgpManager.serverSupportsSecretKeyBackups(connection)) { throw new SmackException.FeatureNotSupportedException("http://jabber.org/protocol/pubsub#access-whitelist"); } - PubSubManager pm = PubSubManager.getInstance(connection, connection.getUser().asBareJid()); + PubSubManager pm = PEPManager.getInstanceFor(connection).getPepPubSubManager(); LeafNode secretKeyNode = pm.getOrCreateLeafNode(PEP_NODE_SECRET_KEY); OpenPgpPubSubUtil.changeAccessModelIfNecessary(secretKeyNode, AccessModel.whitelist); @@ -358,7 +359,7 @@ public class OpenPgpPubSubUtil { * @see * XEP-0373 §5. Synchronizing the Secret Key with a Private PEP Node * - * @param connection {@link XMPPConnection} of the user. + * @param pepManager the PEP manager. * @return the secret key node or null, if it doesn't exist. * * @throws InterruptedException if the thread gets interrupted @@ -367,10 +368,10 @@ public class OpenPgpPubSubUtil { * @throws SmackException.NotConnectedException if we are not connected * @throws SmackException.NoResponseException /watch?v=7U0FzQzJzyI */ - public static SecretkeyElement fetchSecretKey(XMPPConnection connection) + public static SecretkeyElement fetchSecretKey(PEPManager pepManager) throws InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException { - PubSubManager pm = PubSubManager.getInstance(connection, connection.getUser().asBareJid()); + PubSubManager pm = pepManager.getPepPubSubManager(); LeafNode secretKeyNode = pm.getOrCreateLeafNode(PEP_NODE_SECRET_KEY); List> list = secretKeyNode.getItems(1); if (list.size() == 0) { @@ -384,7 +385,7 @@ public class OpenPgpPubSubUtil { /** * Delete the private backup node. * - * @param connection {@link XMPPConnection} of the user. + * @param pepManager the PEP manager. * * @throws XMPPException.XMPPErrorException if there is an XMPP protocol related issue * @throws SmackException.NotConnectedException if we are not connected @@ -392,10 +393,10 @@ public class OpenPgpPubSubUtil { * @throws SmackException.NoResponseException if the server sends no response * @return true if the node existed and was deleted, false if the node did not exist. */ - public static boolean deleteSecretKeyNode(XMPPConnection connection) + public static boolean deleteSecretKeyNode(PEPManager pepManager) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException { - PubSubManager pm = PubSubManager.getInstance(connection); + PubSubManager pm = pepManager.getPepPubSubManager(); return pm.deleteNode(PEP_NODE_SECRET_KEY); }