mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-23 20:42:06 +01:00
Try to fetch pubsub nodes traditionally, then fallback
This commit is contained in:
parent
e157a3015f
commit
2188b6e26f
2 changed files with 69 additions and 17 deletions
|
@ -46,6 +46,8 @@ import org.jivesoftware.smackx.ox.exception.MissingUserIdOnKeyException;
|
||||||
import org.jivesoftware.smackx.ox.exception.SmackOpenPgpException;
|
import org.jivesoftware.smackx.ox.exception.SmackOpenPgpException;
|
||||||
import org.jivesoftware.smackx.ox.util.DecryptedBytesAndMetadata;
|
import org.jivesoftware.smackx.ox.util.DecryptedBytesAndMetadata;
|
||||||
import org.jivesoftware.smackx.ox.util.PubSubDelegate;
|
import org.jivesoftware.smackx.ox.util.PubSubDelegate;
|
||||||
|
import org.jivesoftware.smackx.pubsub.LeafNode;
|
||||||
|
import org.jivesoftware.smackx.pubsub.PubSubException;
|
||||||
|
|
||||||
import org.jxmpp.jid.BareJid;
|
import org.jxmpp.jid.BareJid;
|
||||||
import org.jxmpp.jid.Jid;
|
import org.jxmpp.jid.Jid;
|
||||||
|
@ -142,11 +144,16 @@ public class OpenPgpContact {
|
||||||
*
|
*
|
||||||
* @throws InterruptedException if the thread is interrupted
|
* @throws InterruptedException if the thread is interrupted
|
||||||
* @throws XMPPException.XMPPErrorException in case of an XMPP protocol error
|
* @throws XMPPException.XMPPErrorException in case of an XMPP protocol error
|
||||||
* @throws SmackException in case of an error in Smack
|
|
||||||
* @throws SmackOpenPgpException in case of an OpenPGP exception
|
* @throws SmackOpenPgpException in case of an OpenPGP exception
|
||||||
|
* @throws PubSubException.NotAPubSubNodeException in case the metadata node is not a PubSub node
|
||||||
|
* @throws PubSubException.NotALeafNodeException in case the metadata node is not a {@link LeafNode}
|
||||||
|
* @throws SmackException.NotConnectedException in case we are not connected
|
||||||
|
* @throws SmackException.NoResponseException in case the server doesn't respond
|
||||||
*/
|
*/
|
||||||
public void updateKeys()
|
public void updateKeys()
|
||||||
throws InterruptedException, XMPPException.XMPPErrorException, SmackException, SmackOpenPgpException {
|
throws InterruptedException, XMPPException.XMPPErrorException, SmackOpenPgpException,
|
||||||
|
PubSubException.NotAPubSubNodeException, PubSubException.NotALeafNodeException,
|
||||||
|
SmackException.NotConnectedException, SmackException.NoResponseException {
|
||||||
updateKeys(PubSubDelegate.fetchPubkeysList(connection, getJid()));
|
updateKeys(PubSubDelegate.fetchPubkeysList(connection, getJid()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -167,12 +167,15 @@ public class PubSubDelegate {
|
||||||
* @param connection XMPP connection
|
* @param connection XMPP connection
|
||||||
* @return content of our metadata node.
|
* @return content of our metadata node.
|
||||||
* @throws InterruptedException if the thread gets interrupted.
|
* @throws InterruptedException if the thread gets interrupted.
|
||||||
* @throws SmackException in case of an error in Smack.
|
|
||||||
* @throws XMPPException.XMPPErrorException in case of an XMPP protocol exception.
|
* @throws XMPPException.XMPPErrorException in case of an XMPP protocol exception.
|
||||||
|
* @throws PubSubException.NotAPubSubNodeException in case the queried entity is not a PubSub node
|
||||||
|
* @throws PubSubException.NotALeafNodeException in case the queried node is not a {@link LeafNode}
|
||||||
|
* @throws SmackException.NotConnectedException in case we are not connected
|
||||||
|
* @throws SmackException.NoResponseException in case the server doesn't respond
|
||||||
*/
|
*/
|
||||||
public static PublicKeysListElement fetchPubkeysList(XMPPConnection connection)
|
public static PublicKeysListElement fetchPubkeysList(XMPPConnection connection)
|
||||||
throws InterruptedException, SmackException,
|
throws InterruptedException, XMPPException.XMPPErrorException, PubSubException.NotAPubSubNodeException,
|
||||||
XMPPException.XMPPErrorException {
|
PubSubException.NotALeafNodeException, SmackException.NotConnectedException, SmackException.NoResponseException {
|
||||||
return fetchPubkeysList(connection, connection.getUser().asBareJid());
|
return fetchPubkeysList(connection, connection.getUser().asBareJid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,15 +188,18 @@ public class PubSubDelegate {
|
||||||
* @param contact {@link BareJid} of the user we want to fetch the list from.
|
* @param contact {@link BareJid} of the user we want to fetch the list from.
|
||||||
* @return content of {@code contact}'s metadata node.
|
* @return content of {@code contact}'s metadata node.
|
||||||
* @throws InterruptedException if the thread gets interrupted.
|
* @throws InterruptedException if the thread gets interrupted.
|
||||||
* @throws SmackException in case of an exception in Smack.
|
|
||||||
* @throws XMPPException.XMPPErrorException in case of an XMPP protocol exception.
|
* @throws XMPPException.XMPPErrorException in case of an XMPP protocol exception.
|
||||||
|
* @throws SmackException.NoResponseException in case the server doesn't respond
|
||||||
|
* @throws PubSubException.NotALeafNodeException in case the queried node is not a {@link LeafNode}
|
||||||
|
* @throws SmackException.NotConnectedException in case we are not connected
|
||||||
|
* @throws PubSubException.NotAPubSubNodeException in case the queried entity is not a PubSub node
|
||||||
*/
|
*/
|
||||||
public static PublicKeysListElement fetchPubkeysList(XMPPConnection connection, BareJid contact)
|
public static PublicKeysListElement fetchPubkeysList(XMPPConnection connection, BareJid contact)
|
||||||
throws InterruptedException, SmackException,
|
throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NoResponseException,
|
||||||
XMPPException.XMPPErrorException {
|
PubSubException.NotALeafNodeException, SmackException.NotConnectedException, PubSubException.NotAPubSubNodeException {
|
||||||
PubSubManager pm = PubSubManager.getInstance(connection, contact);
|
PubSubManager pm = PubSubManager.getInstance(connection, contact);
|
||||||
|
|
||||||
LeafNode node = getOpenLeafNode(pm, PEP_NODE_PUBLIC_KEYS);
|
LeafNode node = getLeafNode(pm, PEP_NODE_PUBLIC_KEYS);
|
||||||
List<PayloadItem<PublicKeysListElement>> list = node.getItems(1);
|
List<PayloadItem<PublicKeysListElement>> list = node.getItems(1);
|
||||||
|
|
||||||
if (list.isEmpty()) {
|
if (list.isEmpty()) {
|
||||||
|
@ -263,15 +269,21 @@ public class PubSubDelegate {
|
||||||
* @param v4_fingerprint upper case, hex encoded v4 fingerprint of the contacts key.
|
* @param v4_fingerprint upper case, hex encoded v4 fingerprint of the contacts key.
|
||||||
* @return {@link PubkeyElement} containing the requested public key.
|
* @return {@link PubkeyElement} containing the requested public key.
|
||||||
*
|
*
|
||||||
* @throws InterruptedException if the thread gets interrupted.
|
* @throws InterruptedException if the thread gets interrupted.A
|
||||||
* @throws SmackException in case the node cannot be fetched.
|
|
||||||
* @throws XMPPException.XMPPErrorException in case of an XMPP protocol error.
|
* @throws XMPPException.XMPPErrorException in case of an XMPP protocol error.
|
||||||
|
* @throws PubSubException.NotAPubSubNodeException in case the targeted entity is not a PubSub node.
|
||||||
|
* @throws PubSubException.NotALeafNodeException in case the fetched node is not a {@link LeafNode}.
|
||||||
|
* @throws SmackException.NotConnectedException in case we are not connected.
|
||||||
|
* @throws SmackException.NoResponseException if the server doesn't respond.
|
||||||
*/
|
*/
|
||||||
public static PubkeyElement fetchPubkey(XMPPConnection connection, BareJid contact, OpenPgpV4Fingerprint v4_fingerprint)
|
public static PubkeyElement fetchPubkey(XMPPConnection connection, BareJid contact, OpenPgpV4Fingerprint v4_fingerprint)
|
||||||
throws InterruptedException, SmackException, XMPPException.XMPPErrorException {
|
throws InterruptedException, XMPPException.XMPPErrorException, PubSubException.NotAPubSubNodeException,
|
||||||
|
PubSubException.NotALeafNodeException, SmackException.NotConnectedException, SmackException.NoResponseException {
|
||||||
PubSubManager pm = PubSubManager.getInstance(connection, contact);
|
PubSubManager pm = PubSubManager.getInstance(connection, contact);
|
||||||
|
String nodeName = PEP_NODE_PUBLIC_KEY(v4_fingerprint);
|
||||||
|
|
||||||
|
LeafNode node = getLeafNode(pm, nodeName);
|
||||||
|
|
||||||
LeafNode node = getOpenLeafNode(pm, PEP_NODE_PUBLIC_KEY(v4_fingerprint));
|
|
||||||
List<PayloadItem<PubkeyElement>> list = node.getItems(1);
|
List<PayloadItem<PubkeyElement>> list = node.getItems(1);
|
||||||
|
|
||||||
if (list.isEmpty()) {
|
if (list.isEmpty()) {
|
||||||
|
@ -281,6 +293,40 @@ public class PubSubDelegate {
|
||||||
return list.get(0).getPayload();
|
return list.get(0).getPayload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to get a {@link LeafNode} the traditional way (first query information using disco#info), then query the node.
|
||||||
|
* If that fails, query the node directly.
|
||||||
|
*
|
||||||
|
* @param pm PubSubManager
|
||||||
|
* @param nodeName name of the node
|
||||||
|
* @return node
|
||||||
|
*
|
||||||
|
* @throws XMPPException.XMPPErrorException in case of an XMPP protocol error.
|
||||||
|
* @throws PubSubException.NotALeafNodeException if the queried node is not a {@link LeafNode}.
|
||||||
|
* @throws InterruptedException in case the thread gets interrupted
|
||||||
|
* @throws PubSubException.NotAPubSubNodeException in case the queried entity is not a PubSub node.
|
||||||
|
* @throws SmackException.NotConnectedException in case the connection is not connected.
|
||||||
|
* @throws SmackException.NoResponseException in case the server doesn't respond.
|
||||||
|
*/
|
||||||
|
static LeafNode getLeafNode(PubSubManager pm, String nodeName)
|
||||||
|
throws XMPPException.XMPPErrorException, PubSubException.NotALeafNodeException, InterruptedException,
|
||||||
|
PubSubException.NotAPubSubNodeException, SmackException.NotConnectedException, SmackException.NoResponseException {
|
||||||
|
LeafNode node;
|
||||||
|
try {
|
||||||
|
node = pm.getLeafNode(nodeName);
|
||||||
|
} catch (XMPPException.XMPPErrorException e) {
|
||||||
|
// It might happen, that the server doesn't allow disco#info queries from strangers.
|
||||||
|
// In that case we have to fetch the node directly
|
||||||
|
if (e.getStanzaError().getCondition() == StanzaError.Condition.subscription_required) {
|
||||||
|
node = getOpenLeafNode(pm, nodeName);
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Publishes a {@link SecretkeyElement} to the secret key node.
|
* Publishes a {@link SecretkeyElement} to the secret key node.
|
||||||
* The node will be configured to use the whitelist access model to prevent access from subscribers.
|
* The node will be configured to use the whitelist access model to prevent access from subscribers.
|
||||||
|
@ -368,12 +414,11 @@ public class PubSubDelegate {
|
||||||
* @param nodeName name of the node
|
* @param nodeName name of the node
|
||||||
* @return leafNode
|
* @return leafNode
|
||||||
*
|
*
|
||||||
* @throws SmackException if something goes wrong with reflections.
|
* @throws PubSubException.NotALeafNodeException in case we already have the node cached, but it is not a LeafNode.
|
||||||
* @throws PubSubException.NotALeafNodeException if the node is already in the nodeMap, but is NOT a LeafNode.
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static LeafNode getOpenLeafNode(PubSubManager pubSubManager, String nodeName)
|
public static LeafNode getOpenLeafNode(PubSubManager pubSubManager, String nodeName)
|
||||||
throws SmackException, PubSubException.NotALeafNodeException {
|
throws PubSubException.NotALeafNodeException {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
@ -414,7 +459,7 @@ public class PubSubDelegate {
|
||||||
|
|
||||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException |
|
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException |
|
||||||
NoSuchFieldException e) {
|
NoSuchFieldException e) {
|
||||||
throw new SmackException("Using reflections to create a LeafNode and put it into PubSubManagers nodeMap failed.", e);
|
throw new AssertionError("Using reflections to create a LeafNode and put it into PubSubManagers nodeMap failed.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue