mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-23 20:42:06 +01:00
Rename store methods and fix access to open pubsub nodes
This commit is contained in:
parent
6a756c9a44
commit
613c5d869a
10 changed files with 110 additions and 60 deletions
|
@ -24,7 +24,6 @@ import java.util.logging.Level;
|
||||||
import org.jivesoftware.smack.SmackException;
|
import org.jivesoftware.smack.SmackException;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.packet.Message;
|
import org.jivesoftware.smack.packet.Message;
|
||||||
import org.jivesoftware.smack.roster.Roster;
|
|
||||||
import org.jivesoftware.smack.util.FileUtils;
|
import org.jivesoftware.smack.util.FileUtils;
|
||||||
import org.jivesoftware.smack.util.StringUtils;
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
import org.jivesoftware.smackx.ox.OXInstantMessagingManager;
|
import org.jivesoftware.smackx.ox.OXInstantMessagingManager;
|
||||||
|
@ -76,15 +75,6 @@ public class BasicOpenPgpInstantMessagingIntegrationTest extends AbstractOpenPgp
|
||||||
final SimpleResultSyncPoint bobReceivedMessage = new SimpleResultSyncPoint();
|
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!!!";
|
final String body = "Writing integration tests is an annoying task, but it has to be done, so lets do it!!!";
|
||||||
|
|
||||||
Roster aliceRoster = Roster.getInstanceFor(aliceConnection);
|
|
||||||
Roster bobRoster = Roster.getInstanceFor(bobConnection);
|
|
||||||
|
|
||||||
aliceRoster.setSubscriptionMode(Roster.SubscriptionMode.accept_all);
|
|
||||||
bobRoster.setSubscriptionMode(Roster.SubscriptionMode.accept_all);
|
|
||||||
|
|
||||||
aliceRoster.createEntry(bob, "Bob", null);
|
|
||||||
bobRoster.createEntry(alice, "Alice", null);
|
|
||||||
|
|
||||||
FileBasedPainlessOpenPgpStore aliceStore = new FileBasedPainlessOpenPgpStore(aliceStorePath, new UnprotectedKeysProtector());
|
FileBasedPainlessOpenPgpStore aliceStore = new FileBasedPainlessOpenPgpStore(aliceStorePath, new UnprotectedKeysProtector());
|
||||||
FileBasedPainlessOpenPgpStore bobStore = new FileBasedPainlessOpenPgpStore(bobStorePath, new UnprotectedKeysProtector());
|
FileBasedPainlessOpenPgpStore bobStore = new FileBasedPainlessOpenPgpStore(bobStorePath, new UnprotectedKeysProtector());
|
||||||
|
|
||||||
|
@ -114,8 +104,8 @@ public class BasicOpenPgpInstantMessagingIntegrationTest extends AbstractOpenPgp
|
||||||
aliceFingerprint = aliceOpenPgp.generateAndImportKeyPair(alice);
|
aliceFingerprint = aliceOpenPgp.generateAndImportKeyPair(alice);
|
||||||
bobFingerprint = bobOpenPgp.generateAndImportKeyPair(bob);
|
bobFingerprint = bobOpenPgp.generateAndImportKeyPair(bob);
|
||||||
|
|
||||||
aliceStore.setPrimaryOpenPgpKeyPairFingerprint(aliceFingerprint);
|
aliceStore.setSigningKeyPairFingerprint(aliceFingerprint);
|
||||||
bobStore.setPrimaryOpenPgpKeyPairFingerprint(bobFingerprint);
|
bobStore.setSigningKeyPairFingerprint(bobFingerprint);
|
||||||
|
|
||||||
aliceOpenPgp.announceSupportAndPublish();
|
aliceOpenPgp.announceSupportAndPublish();
|
||||||
bobOpenPgp.announceSupportAndPublish();
|
bobOpenPgp.announceSupportAndPublish();
|
||||||
|
|
|
@ -101,11 +101,11 @@ public class SecretKeyBackupRestoreIntegrationTest extends AbstractOpenPgpIntegr
|
||||||
OpenPgpManager openPgpManager = OpenPgpManager.getInstanceFor(aliceConnection);
|
OpenPgpManager openPgpManager = OpenPgpManager.getInstanceFor(aliceConnection);
|
||||||
openPgpManager.setOpenPgpProvider(beforeProvider);
|
openPgpManager.setOpenPgpProvider(beforeProvider);
|
||||||
|
|
||||||
assertNull(beforeStore.getPrimaryOpenPgpKeyPairFingerprint());
|
assertNull(beforeStore.getSigningKeyPairFingerprint());
|
||||||
|
|
||||||
OpenPgpV4Fingerprint keyFingerprint = openPgpManager.generateAndImportKeyPair(alice);
|
OpenPgpV4Fingerprint keyFingerprint = openPgpManager.generateAndImportKeyPair(alice);
|
||||||
beforeStore.setPrimaryOpenPgpKeyPairFingerprint(keyFingerprint);
|
beforeStore.setSigningKeyPairFingerprint(keyFingerprint);
|
||||||
assertEquals(keyFingerprint, beforeStore.getPrimaryOpenPgpKeyPairFingerprint());
|
assertEquals(keyFingerprint, beforeStore.getSigningKeyPairFingerprint());
|
||||||
|
|
||||||
assertTrue(beforeStore.getAvailableKeyPairFingerprints(alice).contains(keyFingerprint));
|
assertTrue(beforeStore.getAvailableKeyPairFingerprints(alice).contains(keyFingerprint));
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ public class SecretKeyBackupRestoreIntegrationTest extends AbstractOpenPgpIntegr
|
||||||
PainlessOpenPgpProvider afterProvider = new PainlessOpenPgpProvider(alice, afterStore);
|
PainlessOpenPgpProvider afterProvider = new PainlessOpenPgpProvider(alice, afterStore);
|
||||||
openPgpManager.setOpenPgpProvider(afterProvider);
|
openPgpManager.setOpenPgpProvider(afterProvider);
|
||||||
|
|
||||||
assertNull(afterStore.getPrimaryOpenPgpKeyPairFingerprint());
|
assertNull(afterStore.getSigningKeyPairFingerprint());
|
||||||
assertFalse(afterStore.getAvailableKeyPairFingerprints(alice).contains(keyFingerprint));
|
assertFalse(afterStore.getAvailableKeyPairFingerprints(alice).contains(keyFingerprint));
|
||||||
|
|
||||||
OpenPgpV4Fingerprint fingerprint = openPgpManager.restoreSecretKeyServerBackup(new AskForBackupCodeCallback() {
|
OpenPgpV4Fingerprint fingerprint = openPgpManager.restoreSecretKeyServerBackup(new AskForBackupCodeCallback() {
|
||||||
|
@ -142,9 +142,9 @@ public class SecretKeyBackupRestoreIntegrationTest extends AbstractOpenPgpIntegr
|
||||||
|
|
||||||
assertTrue(afterStore.getAvailableKeyPairFingerprints(alice).contains(keyFingerprint));
|
assertTrue(afterStore.getAvailableKeyPairFingerprints(alice).contains(keyFingerprint));
|
||||||
|
|
||||||
afterStore.setPrimaryOpenPgpKeyPairFingerprint(fingerprint);
|
afterStore.setSigningKeyPairFingerprint(fingerprint);
|
||||||
|
|
||||||
assertEquals(keyFingerprint, afterStore.getPrimaryOpenPgpKeyPairFingerprint());
|
assertEquals(keyFingerprint, afterStore.getSigningKeyPairFingerprint());
|
||||||
assertTrue(Arrays.equals(beforeStore.getSecretKeyRings(alice).getEncoded(), afterStore.getSecretKeyRings(alice).getEncoded()));
|
assertTrue(Arrays.equals(beforeStore.getSecretKeyRings(alice).getEncoded(), afterStore.getSecretKeyRings(alice).getEncoded()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,12 +39,12 @@ public abstract class AbstractPainlessOpenPgpStore implements PainlessOpenPgpSto
|
||||||
private final SecretKeyRingProtector secretKeyRingProtector;
|
private final SecretKeyRingProtector secretKeyRingProtector;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OpenPgpV4Fingerprint getPrimaryOpenPgpKeyPairFingerprint() {
|
public OpenPgpV4Fingerprint getSigningKeyPairFingerprint() {
|
||||||
return primaryKeyFingerprint;
|
return primaryKeyFingerprint;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPrimaryOpenPgpKeyPairFingerprint(OpenPgpV4Fingerprint fingerprint) {
|
public void setSigningKeyPairFingerprint(OpenPgpV4Fingerprint fingerprint) {
|
||||||
this.primaryKeyFingerprint = fingerprint;
|
this.primaryKeyFingerprint = fingerprint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -220,7 +220,7 @@ public class PainlessOpenPgpProvider implements OpenPgpProvider {
|
||||||
secretKeyRings = getStore().getSecretKeyRings(owner);
|
secretKeyRings = getStore().getSecretKeyRings(owner);
|
||||||
} catch (PGPException | IOException e) {
|
} catch (PGPException | IOException e) {
|
||||||
LOGGER.log(Level.INFO, "Could not get secret keys of user " + owner);
|
LOGGER.log(Level.INFO, "Could not get secret keys of user " + owner);
|
||||||
throw new MissingOpenPgpKeyPairException(owner, getStore().getPrimaryOpenPgpKeyPairFingerprint());
|
throw new MissingOpenPgpKeyPairException(owner, getStore().getSigningKeyPairFingerprint());
|
||||||
}
|
}
|
||||||
|
|
||||||
SecretKeyRingProtector protector = getStore().getSecretKeyProtector();
|
SecretKeyRingProtector protector = getStore().getSecretKeyProtector();
|
||||||
|
|
|
@ -90,8 +90,8 @@ public class DryOxEncryptionTest extends OxTestSuite {
|
||||||
OpenPgpV4Fingerprint romeoFinger = romeoProvider.importSecretKey(romemo,
|
OpenPgpV4Fingerprint romeoFinger = romeoProvider.importSecretKey(romemo,
|
||||||
BCUtil.getDecodedBytes(TestKeys.ROMEO_PRIV.getBytes(UTF8)));
|
BCUtil.getDecodedBytes(TestKeys.ROMEO_PRIV.getBytes(UTF8)));
|
||||||
|
|
||||||
julietStore.setPrimaryOpenPgpKeyPairFingerprint(julietFinger);
|
julietStore.setSigningKeyPairFingerprint(julietFinger);
|
||||||
romeoStore.setPrimaryOpenPgpKeyPairFingerprint(romeoFinger);
|
romeoStore.setSigningKeyPairFingerprint(romeoFinger);
|
||||||
|
|
||||||
byte[] julietPubBytes = julietStore.getPublicKeyRingBytes(juliet, julietFinger);
|
byte[] julietPubBytes = julietStore.getPublicKeyRingBytes(juliet, julietFinger);
|
||||||
byte[] romeoPubBytes = romeoStore.getPublicKeyRingBytes(romemo, romeoFinger);
|
byte[] romeoPubBytes = romeoStore.getPublicKeyRingBytes(romemo, romeoFinger);
|
||||||
|
|
|
@ -219,7 +219,7 @@ public final class OpenPgpManager extends Manager {
|
||||||
*/
|
*/
|
||||||
public OpenPgpV4Fingerprint getOurFingerprint() {
|
public OpenPgpV4Fingerprint getOurFingerprint() {
|
||||||
throwIfNoProviderSet();
|
throwIfNoProviderSet();
|
||||||
return provider.getStore().getPrimaryOpenPgpKeyPairFingerprint();
|
return provider.getStore().getSigningKeyPairFingerprint();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -362,12 +362,9 @@ public final class OpenPgpManager extends Manager {
|
||||||
* @throws SmackOpenPgpException
|
* @throws SmackOpenPgpException
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
* @throws XMPPException.XMPPErrorException
|
* @throws XMPPException.XMPPErrorException
|
||||||
* @throws SmackException.NotConnectedException
|
|
||||||
* @throws SmackException.NoResponseException
|
|
||||||
*/
|
*/
|
||||||
private OpenPgpFingerprints determineContactsKeys(BareJid jid)
|
private OpenPgpFingerprints determineContactsKeys(BareJid jid)
|
||||||
throws SmackOpenPgpException, InterruptedException, XMPPException.XMPPErrorException,
|
throws SmackOpenPgpException, InterruptedException, XMPPException.XMPPErrorException {
|
||||||
SmackException.NotConnectedException, SmackException.NoResponseException {
|
|
||||||
Set<OpenPgpV4Fingerprint> announced = provider.getStore().getAnnouncedKeysFingerprints(jid).keySet();
|
Set<OpenPgpV4Fingerprint> announced = provider.getStore().getAnnouncedKeysFingerprints(jid).keySet();
|
||||||
Set<OpenPgpV4Fingerprint> available = provider.getStore().getAvailableKeysFingerprints(jid).keySet();
|
Set<OpenPgpV4Fingerprint> available = provider.getStore().getAvailableKeysFingerprints(jid).keySet();
|
||||||
Map<OpenPgpV4Fingerprint, Throwable> unfetched = new HashMap<>();
|
Map<OpenPgpV4Fingerprint, Throwable> unfetched = new HashMap<>();
|
||||||
|
@ -382,7 +379,7 @@ public final class OpenPgpManager extends Manager {
|
||||||
processPublicKey(pubkeyElement, jid);
|
processPublicKey(pubkeyElement, jid);
|
||||||
available.add(f);
|
available.add(f);
|
||||||
|
|
||||||
} catch (PubSubException.NotAPubSubNodeException | PubSubException.NotALeafNodeException e) {
|
} catch (SmackException e) {
|
||||||
LOGGER.log(Level.WARNING, "Could not fetch public key " + f.toString() + " of user " + jid.toString(), e);
|
LOGGER.log(Level.WARNING, "Could not fetch public key " + f.toString() + " of user " + jid.toString(), e);
|
||||||
unfetched.put(f, e);
|
unfetched.put(f, e);
|
||||||
} catch (MissingUserIdOnKeyException e) {
|
} catch (MissingUserIdOnKeyException e) {
|
||||||
|
@ -422,9 +419,8 @@ public final class OpenPgpManager extends Manager {
|
||||||
};
|
};
|
||||||
|
|
||||||
public void requestMetadataUpdate(BareJid contact)
|
public void requestMetadataUpdate(BareJid contact)
|
||||||
throws InterruptedException, PubSubException.NotALeafNodeException, SmackException.NoResponseException,
|
throws InterruptedException, SmackException,
|
||||||
SmackException.NotConnectedException, XMPPException.XMPPErrorException,
|
XMPPException.XMPPErrorException {
|
||||||
PubSubException.NotAPubSubNodeException {
|
|
||||||
PublicKeysListElement metadata = PubSubDelegate.fetchPubkeysList(connection(), contact);
|
PublicKeysListElement metadata = PubSubDelegate.fetchPubkeysList(connection(), contact);
|
||||||
processPublicKeysListElement(contact, metadata);
|
processPublicKeysListElement(contact, metadata);
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ public interface OpenPgpProvider {
|
||||||
throws MissingOpenPgpKeyPairException, MissingOpenPgpPublicKeyException, SmackOpenPgpException, IOException;
|
throws MissingOpenPgpKeyPairException, MissingOpenPgpPublicKeyException, SmackOpenPgpException, IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sign a {@link SignElement} with th users signing key.
|
* Sign a {@link SignElement} with the users signing key.
|
||||||
* The resulting byte array contains the signed byte representation of the {@link SignElement}.
|
* The resulting byte array contains the signed byte representation of the {@link SignElement}.
|
||||||
*
|
*
|
||||||
* @see <a href="https://xmpp.org/extensions/xep-0373.html#exchange">XEP-0373 §3.1</a>
|
* @see <a href="https://xmpp.org/extensions/xep-0373.html#exchange">XEP-0373 §3.1</a>
|
||||||
|
|
|
@ -37,7 +37,7 @@ public interface OpenPgpStore {
|
||||||
*
|
*
|
||||||
* @return fingerprint of the primary OpenPGP key pair.
|
* @return fingerprint of the primary OpenPGP key pair.
|
||||||
*/
|
*/
|
||||||
OpenPgpV4Fingerprint getPrimaryOpenPgpKeyPairFingerprint();
|
OpenPgpV4Fingerprint getSigningKeyPairFingerprint();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the {@link OpenPgpV4Fingerprint} of the primary OpenPGP key pair.
|
* Set the {@link OpenPgpV4Fingerprint} of the primary OpenPGP key pair.
|
||||||
|
@ -45,7 +45,7 @@ public interface OpenPgpStore {
|
||||||
*
|
*
|
||||||
* @param fingerprint {@link OpenPgpV4Fingerprint} of the new primary key pair.
|
* @param fingerprint {@link OpenPgpV4Fingerprint} of the new primary key pair.
|
||||||
*/
|
*/
|
||||||
void setPrimaryOpenPgpKeyPairFingerprint(OpenPgpV4Fingerprint fingerprint);
|
void setSigningKeyPairFingerprint(OpenPgpV4Fingerprint fingerprint);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a {@link Set} containing the {@link OpenPgpV4Fingerprint}s of the master keys of all available
|
* Return a {@link Set} containing the {@link OpenPgpV4Fingerprint}s of the master keys of all available
|
||||||
|
@ -127,6 +127,8 @@ public interface OpenPgpStore {
|
||||||
* @param owner owner of the key
|
* @param owner owner of the key
|
||||||
* @param fingerprint fingerprint of the key
|
* @param fingerprint fingerprint of the key
|
||||||
* @return byte representation of the public key.
|
* @return byte representation of the public key.
|
||||||
|
*
|
||||||
|
* @throws MissingOpenPgpPublicKeyException if the key does not exist.
|
||||||
*/
|
*/
|
||||||
byte[] getPublicKeyRingBytes(BareJid owner, OpenPgpV4Fingerprint fingerprint)
|
byte[] getPublicKeyRingBytes(BareJid owner, OpenPgpV4Fingerprint fingerprint)
|
||||||
throws MissingOpenPgpPublicKeyException;
|
throws MissingOpenPgpPublicKeyException;
|
||||||
|
@ -137,6 +139,8 @@ public interface OpenPgpStore {
|
||||||
* @param owner owner of the key
|
* @param owner owner of the key
|
||||||
* @param fingerprint fingerprint of the key
|
* @param fingerprint fingerprint of the key
|
||||||
* @return byte representation of the secret key.
|
* @return byte representation of the secret key.
|
||||||
|
*
|
||||||
|
* @throws MissingOpenPgpKeyPairException if the secret key doesn't exist.
|
||||||
*/
|
*/
|
||||||
byte[] getSecretKeyRingBytes(BareJid owner, OpenPgpV4Fingerprint fingerprint)
|
byte[] getSecretKeyRingBytes(BareJid owner, OpenPgpV4Fingerprint fingerprint)
|
||||||
throws MissingOpenPgpKeyPairException;
|
throws MissingOpenPgpKeyPairException;
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class OpenPgpContact {
|
||||||
OpenPgpFingerprints contactsFingerprints) {
|
OpenPgpFingerprints contactsFingerprints) {
|
||||||
this.cryptoProvider = cryptoProvider;
|
this.cryptoProvider = cryptoProvider;
|
||||||
this.jid = jid;
|
this.jid = jid;
|
||||||
this.singingKey = cryptoProvider.getStore().getPrimaryOpenPgpKeyPairFingerprint();
|
this.singingKey = cryptoProvider.getStore().getSigningKeyPairFingerprint();
|
||||||
this.ourFingerprints = ourFingerprints;
|
this.ourFingerprints = ourFingerprints;
|
||||||
this.contactsFingerprints = contactsFingerprints;
|
this.contactsFingerprints = contactsFingerprints;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,12 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.ox.util;
|
package org.jivesoftware.smackx.ox.util;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
@ -35,6 +39,7 @@ import org.jivesoftware.smackx.pubsub.AccessModel;
|
||||||
import org.jivesoftware.smackx.pubsub.ConfigureForm;
|
import org.jivesoftware.smackx.pubsub.ConfigureForm;
|
||||||
import org.jivesoftware.smackx.pubsub.Item;
|
import org.jivesoftware.smackx.pubsub.Item;
|
||||||
import org.jivesoftware.smackx.pubsub.LeafNode;
|
import org.jivesoftware.smackx.pubsub.LeafNode;
|
||||||
|
import org.jivesoftware.smackx.pubsub.Node;
|
||||||
import org.jivesoftware.smackx.pubsub.PayloadItem;
|
import org.jivesoftware.smackx.pubsub.PayloadItem;
|
||||||
import org.jivesoftware.smackx.pubsub.PubSubException;
|
import org.jivesoftware.smackx.pubsub.PubSubException;
|
||||||
import org.jivesoftware.smackx.pubsub.PubSubManager;
|
import org.jivesoftware.smackx.pubsub.PubSubManager;
|
||||||
|
@ -157,19 +162,16 @@ public class PubSubDelegate {
|
||||||
*
|
*
|
||||||
* @return content of our metadata node.
|
* @return content of our metadata node.
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
* @throws PubSubException.NotALeafNodeException
|
* @throws SmackException
|
||||||
* @throws SmackException.NoResponseException
|
|
||||||
* @throws SmackException.NotConnectedException
|
|
||||||
* @throws XMPPException.XMPPErrorException
|
* @throws XMPPException.XMPPErrorException
|
||||||
* @throws PubSubException.NotAPubSubNodeException
|
|
||||||
*/
|
*/
|
||||||
public static PublicKeysListElement fetchPubkeysList(XMPPConnection connection)
|
public static PublicKeysListElement fetchPubkeysList(XMPPConnection connection)
|
||||||
throws InterruptedException, PubSubException.NotALeafNodeException, SmackException.NoResponseException,
|
throws InterruptedException, SmackException,
|
||||||
SmackException.NotConnectedException, XMPPException.XMPPErrorException,
|
XMPPException.XMPPErrorException {
|
||||||
PubSubException.NotAPubSubNodeException {
|
|
||||||
return fetchPubkeysList(connection, connection.getUser().asBareJid());
|
return fetchPubkeysList(connection, connection.getUser().asBareJid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Consult the public key metadata node of {@code contact} to fetch the list of their published OpenPGP public keys.
|
* Consult the public key metadata node of {@code contact} to fetch the list of their published OpenPGP public keys.
|
||||||
* TODO: Add @see which points to the (for now missing) respective example in XEP-0373.
|
* TODO: Add @see which points to the (for now missing) respective example in XEP-0373.
|
||||||
|
@ -177,19 +179,15 @@ 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
|
* @throws InterruptedException
|
||||||
* @throws PubSubException.NotALeafNodeException
|
* @throws SmackException
|
||||||
* @throws SmackException.NoResponseException
|
|
||||||
* @throws SmackException.NotConnectedException
|
|
||||||
* @throws XMPPException.XMPPErrorException
|
* @throws XMPPException.XMPPErrorException
|
||||||
* @throws PubSubException.NotAPubSubNodeException
|
|
||||||
*/
|
*/
|
||||||
public static PublicKeysListElement fetchPubkeysList(XMPPConnection connection, BareJid contact)
|
public static PublicKeysListElement fetchPubkeysList(XMPPConnection connection, BareJid contact)
|
||||||
throws InterruptedException, PubSubException.NotALeafNodeException, SmackException.NoResponseException,
|
throws InterruptedException, SmackException,
|
||||||
SmackException.NotConnectedException, XMPPException.XMPPErrorException,
|
XMPPException.XMPPErrorException {
|
||||||
PubSubException.NotAPubSubNodeException {
|
|
||||||
PubSubManager pm = PubSubManager.getInstance(connection, contact);
|
PubSubManager pm = PubSubManager.getInstance(connection, contact);
|
||||||
|
|
||||||
LeafNode node = pm.getLeafNode(PEP_NODE_PUBLIC_KEYS);
|
LeafNode node = getOpenLeafNode(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()) {
|
||||||
|
@ -247,6 +245,7 @@ public class PubSubDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch the OpenPGP public key of a {@code contact}, identified by its OpenPGP {@code v4_fingerprint}.
|
* Fetch the OpenPGP public key of a {@code contact}, identified by its OpenPGP {@code v4_fingerprint}.
|
||||||
*
|
*
|
||||||
|
@ -255,20 +254,16 @@ public class PubSubDelegate {
|
||||||
* @param contact {@link BareJid} of the contact we want to fetch a key from.
|
* @param contact {@link BareJid} of the contact we want to fetch a key from.
|
||||||
* @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
|
*
|
||||||
* @throws PubSubException.NotALeafNodeException
|
* @throws InterruptedException if we get interrupted.
|
||||||
* @throws SmackException.NoResponseException
|
* @throws SmackException in case the node cannot be fetched.
|
||||||
* @throws SmackException.NotConnectedException
|
|
||||||
* @throws XMPPException.XMPPErrorException
|
* @throws XMPPException.XMPPErrorException
|
||||||
* @throws PubSubException.NotAPubSubNodeException
|
|
||||||
*/
|
*/
|
||||||
public static PubkeyElement fetchPubkey(XMPPConnection connection, BareJid contact, OpenPgpV4Fingerprint v4_fingerprint)
|
public static PubkeyElement fetchPubkey(XMPPConnection connection, BareJid contact, OpenPgpV4Fingerprint v4_fingerprint)
|
||||||
throws InterruptedException, PubSubException.NotALeafNodeException, SmackException.NoResponseException,
|
throws InterruptedException, SmackException, XMPPException.XMPPErrorException {
|
||||||
SmackException.NotConnectedException, XMPPException.XMPPErrorException,
|
|
||||||
PubSubException.NotAPubSubNodeException {
|
|
||||||
PubSubManager pm = PubSubManager.getInstance(connection, contact);
|
PubSubManager pm = PubSubManager.getInstance(connection, contact);
|
||||||
|
|
||||||
LeafNode node = pm.getLeafNode(PEP_NODE_PUBLIC_KEY(v4_fingerprint));
|
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()) {
|
||||||
|
@ -352,4 +347,69 @@ public class PubSubDelegate {
|
||||||
PubSubManager pm = PubSubManager.getInstance(connection);
|
PubSubManager pm = PubSubManager.getInstance(connection);
|
||||||
pm.deleteNode(PEP_NODE_SECRET_KEY);
|
pm.deleteNode(PEP_NODE_SECRET_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use reflection magic to get a {@link LeafNode} without doing a disco#info query.
|
||||||
|
* This method is useful for fetching nodes that are configured with the access model 'open', since
|
||||||
|
* some servers that announce support for that access model do not allow disco#info queries from contacts
|
||||||
|
* which are not subscribed to the node owner. Therefore this method fetches the node directly and puts it
|
||||||
|
* into the {@link PubSubManager}s node map.
|
||||||
|
*
|
||||||
|
* @see <a href="https://github.com/processone/ejabberd/issues/2483">Ejabberd bug tracker about the issue</a>
|
||||||
|
*
|
||||||
|
* @param pubSubManager pubsub manager
|
||||||
|
* @param nodeName name of the node
|
||||||
|
* @return leafNode
|
||||||
|
*
|
||||||
|
* @throws SmackException if something goes wrong with reflections.
|
||||||
|
* @throws PubSubException.NotALeafNodeException if the node is already in the nodeMap, but is NOT a LeafNode.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static LeafNode getOpenLeafNode(PubSubManager pubSubManager, String nodeName)
|
||||||
|
throws SmackException, PubSubException.NotALeafNodeException {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Get access to the PubSubManager's nodeMap
|
||||||
|
Field field = pubSubManager.getClass().getDeclaredField("nodeMap");
|
||||||
|
field.setAccessible(true);
|
||||||
|
// CHECKSTYLE:OFF
|
||||||
|
Map<String, Node> nodeMap = (Map) field.get(pubSubManager);
|
||||||
|
// CHECKSTYLE:ON
|
||||||
|
|
||||||
|
// Check, if the node already exists
|
||||||
|
Node existingNode = nodeMap.get(nodeName);
|
||||||
|
if (existingNode != null) {
|
||||||
|
|
||||||
|
if (existingNode instanceof LeafNode) {
|
||||||
|
// We already know that node
|
||||||
|
return (LeafNode) existingNode;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Throw a new NotALeafNodeException, as the node is not a LeafNode.
|
||||||
|
// Again use reflections to access the exceptions constructor.
|
||||||
|
Constructor<PubSubException.NotALeafNodeException> exceptionConstructor =
|
||||||
|
PubSubException.NotALeafNodeException.class.getDeclaredConstructor(String.class, BareJid.class);
|
||||||
|
exceptionConstructor.setAccessible(true);
|
||||||
|
throw exceptionConstructor.newInstance(nodeName, pubSubManager.getServiceJid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Node does not exist. Create the node
|
||||||
|
Constructor<LeafNode> constructor;
|
||||||
|
constructor = LeafNode.class.getDeclaredConstructor(PubSubManager.class, String.class);
|
||||||
|
constructor.setAccessible(true);
|
||||||
|
LeafNode node = constructor.newInstance(pubSubManager, nodeName);
|
||||||
|
|
||||||
|
// Add it to the node map
|
||||||
|
nodeMap.put(nodeName, node);
|
||||||
|
|
||||||
|
// And return
|
||||||
|
return node;
|
||||||
|
|
||||||
|
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException |
|
||||||
|
NoSuchFieldException e) {
|
||||||
|
throw new SmackException("Using reflections to create a LeafNode and put it into PubSubManagers nodeMap failed.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue