use publish-options instead of always pushing node configuration
This commit is contained in:
parent
8d6b2074cb
commit
9a57673130
|
@ -48,6 +48,7 @@ import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
import eu.siacs.conversations.utils.CryptoHelper;
|
import eu.siacs.conversations.utils.CryptoHelper;
|
||||||
import eu.siacs.conversations.utils.SerialSingleThreadExecutor;
|
import eu.siacs.conversations.utils.SerialSingleThreadExecutor;
|
||||||
import eu.siacs.conversations.xml.Element;
|
import eu.siacs.conversations.xml.Element;
|
||||||
|
import eu.siacs.conversations.xml.Namespace;
|
||||||
import eu.siacs.conversations.xmpp.OnAdvancedStreamFeaturesLoaded;
|
import eu.siacs.conversations.xmpp.OnAdvancedStreamFeaturesLoaded;
|
||||||
import eu.siacs.conversations.xmpp.OnIqPacketReceived;
|
import eu.siacs.conversations.xmpp.OnIqPacketReceived;
|
||||||
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
||||||
|
@ -214,7 +215,6 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
putDevicesForJid(account.getJid().toBareJid().toPreppedString(), deviceIds, store);
|
putDevicesForJid(account.getJid().toBareJid().toPreppedString(), deviceIds, store);
|
||||||
for (String address : store.getKnownAddresses()) {
|
for (String address : store.getKnownAddresses()) {
|
||||||
deviceIds = store.getSubDeviceSessions(address);
|
deviceIds = store.getSubDeviceSessions(address);
|
||||||
Log.d(Config.LOGTAG,account.getJid().toBareJid()+" adding device ids for "+address+" "+deviceIds);
|
|
||||||
putDevicesForJid(address, deviceIds, store);
|
putDevicesForJid(address, deviceIds, store);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,16 +437,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
}
|
}
|
||||||
Set<Integer> deviceIds = new HashSet<>();
|
Set<Integer> deviceIds = new HashSet<>();
|
||||||
deviceIds.add(getOwnDeviceId());
|
deviceIds.add(getOwnDeviceId());
|
||||||
IqPacket publish = mXmppConnectionService.getIqGenerator().publishDeviceIds(deviceIds);
|
publishDeviceIdsAndRefineAccessModel(deviceIds);
|
||||||
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Wiping all other devices from Pep:" + publish);
|
|
||||||
mXmppConnectionService.sendIqPacket(account, publish, new OnIqPacketReceived() {
|
|
||||||
@Override
|
|
||||||
public void onIqPacketReceived(Account account, IqPacket packet) {
|
|
||||||
if (packet.getType() == IqPacket.TYPE.RESULT) {
|
|
||||||
mXmppConnectionService.pushNodeConfiguration(account, AxolotlService.PEP_DEVICE_LIST, PublishOptions.openAccess(), null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void distrustFingerprint(final String fingerprint) {
|
public void distrustFingerprint(final String fingerprint) {
|
||||||
|
@ -513,17 +504,40 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
numPublishTriesOnEmptyPep = 0;
|
numPublishTriesOnEmptyPep = 0;
|
||||||
}
|
}
|
||||||
deviceIdsCopy.add(getOwnDeviceId());
|
deviceIdsCopy.add(getOwnDeviceId());
|
||||||
IqPacket publish = mXmppConnectionService.getIqGenerator().publishDeviceIds(deviceIdsCopy);
|
publishDeviceIdsAndRefineAccessModel(deviceIdsCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void publishDeviceIdsAndRefineAccessModel(Set<Integer> ids) {
|
||||||
|
publishDeviceIdsAndRefineAccessModel(ids,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void publishDeviceIdsAndRefineAccessModel(final Set<Integer> ids, final boolean firstAttempt) {
|
||||||
|
final Bundle publishOptions = account.getXmppConnection().getFeatures().pepPublishOptions() ? PublishOptions.openAccess() : null;
|
||||||
|
IqPacket publish = mXmppConnectionService.getIqGenerator().publishDeviceIds(ids, publishOptions);
|
||||||
ownPushPending.set(true);
|
ownPushPending.set(true);
|
||||||
mXmppConnectionService.sendIqPacket(account, publish, new OnIqPacketReceived() {
|
mXmppConnectionService.sendIqPacket(account, publish, new OnIqPacketReceived() {
|
||||||
@Override
|
@Override
|
||||||
public void onIqPacketReceived(Account account, IqPacket packet) {
|
public void onIqPacketReceived(Account account, IqPacket packet) {
|
||||||
|
Element error = packet.getType() == IqPacket.TYPE.ERROR ? packet.findChild("error") : null;
|
||||||
|
if (firstAttempt && error != null && error.hasChild("precondition-not-met",Namespace.PUBSUB_ERROR)) {
|
||||||
|
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": precondition wasn't met for device list. pushing node configuration");
|
||||||
|
mXmppConnectionService.pushNodeConfiguration(account, AxolotlService.PEP_DEVICE_LIST, publishOptions, new XmppConnectionService.OnConfigurationPushed() {
|
||||||
|
@Override
|
||||||
|
public void onPushSucceeded() {
|
||||||
|
publishDeviceIdsAndRefineAccessModel(ids, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPushFailed() {
|
||||||
|
publishDeviceIdsAndRefineAccessModel(ids, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
ownPushPending.set(false);
|
ownPushPending.set(false);
|
||||||
if (packet.getType() == IqPacket.TYPE.ERROR) {
|
if (packet.getType() == IqPacket.TYPE.ERROR) {
|
||||||
pepBroken = true;
|
pepBroken = true;
|
||||||
Log.d(Config.LOGTAG, getLogprefix(account) + "Error received while publishing own device id" + packet.findChild("error"));
|
Log.d(Config.LOGTAG, getLogprefix(account) + "Error received while publishing own device id" + packet.findChild("error"));
|
||||||
} else if (packet.getType() != IqPacket.TYPE.TIMEOUT) {
|
}
|
||||||
mXmppConnectionService.pushNodeConfiguration(account, AxolotlService.PEP_DEVICE_LIST, PublishOptions.openAccess(), null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -683,18 +697,38 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
Set<PreKeyRecord> preKeyRecords,
|
Set<PreKeyRecord> preKeyRecords,
|
||||||
final boolean announceAfter,
|
final boolean announceAfter,
|
||||||
final boolean wipe) {
|
final boolean wipe) {
|
||||||
|
publishDeviceBundle(signedPreKeyRecord,preKeyRecords,announceAfter,wipe,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void publishDeviceBundle(final SignedPreKeyRecord signedPreKeyRecord,
|
||||||
|
final Set<PreKeyRecord> preKeyRecords,
|
||||||
|
final boolean announceAfter,
|
||||||
|
final boolean wipe,
|
||||||
|
final boolean firstAttempt) {
|
||||||
|
final Bundle publishOptions = account.getXmppConnection().getFeatures().pepPublishOptions() ? PublishOptions.openAccess() : null;
|
||||||
IqPacket publish = mXmppConnectionService.getIqGenerator().publishBundles(
|
IqPacket publish = mXmppConnectionService.getIqGenerator().publishBundles(
|
||||||
signedPreKeyRecord, axolotlStore.getIdentityKeyPair().getPublicKey(),
|
signedPreKeyRecord, axolotlStore.getIdentityKeyPair().getPublicKey(),
|
||||||
preKeyRecords, getOwnDeviceId());
|
preKeyRecords, getOwnDeviceId(),publishOptions);
|
||||||
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + ": Bundle " + getOwnDeviceId() + " in PEP not current. Publishing...");
|
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + ": Bundle " + getOwnDeviceId() + " in PEP not current. Publishing...");
|
||||||
mXmppConnectionService.sendIqPacket(account, publish, new OnIqPacketReceived() {
|
mXmppConnectionService.sendIqPacket(account, publish, new OnIqPacketReceived() {
|
||||||
@Override
|
@Override
|
||||||
public void onIqPacketReceived(final Account account, IqPacket packet) {
|
public void onIqPacketReceived(final Account account, IqPacket packet) {
|
||||||
if (packet.getType() == IqPacket.TYPE.RESULT) {
|
Element error = packet.getType() == IqPacket.TYPE.ERROR ? packet.findChild("error") : null;
|
||||||
|
if (firstAttempt && error != null && error.hasChild("precondition-not-met", Namespace.PUBSUB_ERROR)) {
|
||||||
|
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": precondition wasn't met for bundle. pushing node configuration");
|
||||||
final String node = AxolotlService.PEP_BUNDLES + ":" + getOwnDeviceId();
|
final String node = AxolotlService.PEP_BUNDLES + ":" + getOwnDeviceId();
|
||||||
mXmppConnectionService.pushNodeConfiguration(account, node, PublishOptions.openAccess(), new XmppConnectionService.OnConfigurationPushed() {
|
mXmppConnectionService.pushNodeConfiguration(account, node, publishOptions, new XmppConnectionService.OnConfigurationPushed() {
|
||||||
@Override
|
@Override
|
||||||
public void onPushSucceeded() {
|
public void onPushSucceeded() {
|
||||||
|
publishDeviceBundle(signedPreKeyRecord,preKeyRecords, announceAfter, wipe, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPushFailed() {
|
||||||
|
publishDeviceBundle(signedPreKeyRecord,preKeyRecords, announceAfter, wipe, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} if (packet.getType() == IqPacket.TYPE.RESULT) {
|
||||||
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Successfully published bundle. ");
|
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Successfully published bundle. ");
|
||||||
if (wipe) {
|
if (wipe) {
|
||||||
wipeOtherPepDevices();
|
wipeOtherPepDevices();
|
||||||
|
@ -702,13 +736,6 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
Log.d(Config.LOGTAG, getLogprefix(account) + "Announcing device " + getOwnDeviceId());
|
Log.d(Config.LOGTAG, getLogprefix(account) + "Announcing device " + getOwnDeviceId());
|
||||||
publishOwnDeviceIdIfNeeded();
|
publishOwnDeviceIdIfNeeded();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPushFailed() {
|
|
||||||
Log.d(Config.LOGTAG,"unable to change access model for pubsub node");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (packet.getType() == IqPacket.TYPE.ERROR) {
|
} else if (packet.getType() == IqPacket.TYPE.ERROR) {
|
||||||
pepBroken = true;
|
pepBroken = true;
|
||||||
Log.d(Config.LOGTAG, getLogprefix(account) + "Error received while publishing bundle: " + packet.findChild("error"));
|
Log.d(Config.LOGTAG, getLogprefix(account) + "Error received while publishing bundle: " + packet.findChild("error"));
|
||||||
|
|
|
@ -91,16 +91,24 @@ public class IqGenerator extends AbstractGenerator {
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IqPacket publish(final String node, final Element item) {
|
protected IqPacket publish(final String node, final Element item, final Bundle options) {
|
||||||
final IqPacket packet = new IqPacket(IqPacket.TYPE.SET);
|
final IqPacket packet = new IqPacket(IqPacket.TYPE.SET);
|
||||||
final Element pubsub = packet.addChild("pubsub",
|
final Element pubsub = packet.addChild("pubsub",
|
||||||
"http://jabber.org/protocol/pubsub");
|
"http://jabber.org/protocol/pubsub");
|
||||||
final Element publish = pubsub.addChild("publish");
|
final Element publish = pubsub.addChild("publish");
|
||||||
publish.setAttribute("node", node);
|
publish.setAttribute("node", node);
|
||||||
publish.addChild(item);
|
publish.addChild(item);
|
||||||
|
if (options != null) {
|
||||||
|
final Element publishOptions = pubsub.addChild("publish-options");
|
||||||
|
publishOptions.addChild(Data.create(Namespace.PUBSUB_PUBLISH_OPTIONS, options));
|
||||||
|
}
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected IqPacket publish(final String node, final Element item) {
|
||||||
|
return publish(node,item,null);
|
||||||
|
}
|
||||||
|
|
||||||
protected IqPacket retrieve(String node, Element item) {
|
protected IqPacket retrieve(String node, Element item) {
|
||||||
final IqPacket packet = new IqPacket(IqPacket.TYPE.GET);
|
final IqPacket packet = new IqPacket(IqPacket.TYPE.GET);
|
||||||
final Element pubsub = packet.addChild("pubsub",
|
final Element pubsub = packet.addChild("pubsub",
|
||||||
|
@ -184,7 +192,7 @@ public class IqGenerator extends AbstractGenerator {
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IqPacket publishDeviceIds(final Set<Integer> ids) {
|
public IqPacket publishDeviceIds(final Set<Integer> ids, final Bundle publishOptions) {
|
||||||
final Element item = new Element("item");
|
final Element item = new Element("item");
|
||||||
final Element list = item.addChild("list", AxolotlService.PEP_PREFIX);
|
final Element list = item.addChild("list", AxolotlService.PEP_PREFIX);
|
||||||
for(Integer id:ids) {
|
for(Integer id:ids) {
|
||||||
|
@ -192,11 +200,11 @@ public class IqGenerator extends AbstractGenerator {
|
||||||
device.setAttribute("id", id);
|
device.setAttribute("id", id);
|
||||||
list.addChild(device);
|
list.addChild(device);
|
||||||
}
|
}
|
||||||
return publish(AxolotlService.PEP_DEVICE_LIST, item);
|
return publish(AxolotlService.PEP_DEVICE_LIST, item, publishOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IqPacket publishBundles(final SignedPreKeyRecord signedPreKeyRecord, final IdentityKey identityKey,
|
public IqPacket publishBundles(final SignedPreKeyRecord signedPreKeyRecord, final IdentityKey identityKey,
|
||||||
final Set<PreKeyRecord> preKeyRecords, final int deviceId) {
|
final Set<PreKeyRecord> preKeyRecords, final int deviceId, Bundle publishOptions) {
|
||||||
final Element item = new Element("item");
|
final Element item = new Element("item");
|
||||||
final Element bundle = item.addChild("bundle", AxolotlService.PEP_PREFIX);
|
final Element bundle = item.addChild("bundle", AxolotlService.PEP_PREFIX);
|
||||||
final Element signedPreKeyPublic = bundle.addChild("signedPreKeyPublic");
|
final Element signedPreKeyPublic = bundle.addChild("signedPreKeyPublic");
|
||||||
|
@ -215,7 +223,7 @@ public class IqGenerator extends AbstractGenerator {
|
||||||
prekey.setContent(Base64.encodeToString(preKeyRecord.getKeyPair().getPublicKey().serialize(), Base64.DEFAULT));
|
prekey.setContent(Base64.encodeToString(preKeyRecord.getKeyPair().getPublicKey().serialize(), Base64.DEFAULT));
|
||||||
}
|
}
|
||||||
|
|
||||||
return publish(AxolotlService.PEP_BUNDLES+":"+deviceId, item);
|
return publish(AxolotlService.PEP_BUNDLES+":"+deviceId, item, publishOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IqPacket publishVerification(byte[] signature, X509Certificate[] certificates, final int deviceId) {
|
public IqPacket publishVerification(byte[] signature, X509Certificate[] certificates, final int deviceId) {
|
||||||
|
|
|
@ -13,4 +13,6 @@ public final class Namespace {
|
||||||
public static final String OOB = "jabber:x:oob";
|
public static final String OOB = "jabber:x:oob";
|
||||||
public static final String SASL = "urn:ietf:params:xml:ns:xmpp-sasl";
|
public static final String SASL = "urn:ietf:params:xml:ns:xmpp-sasl";
|
||||||
public static final String TLS = "urn:ietf:params:xml:ns:xmpp-tls";
|
public static final String TLS = "urn:ietf:params:xml:ns:xmpp-tls";
|
||||||
|
public static final String PUBSUB_PUBLISH_OPTIONS = "http://jabber.org/protocol/pubsub#publish-options";
|
||||||
|
public static final String PUBSUB_ERROR = "http://jabber.org/protocol/pubsub#errors";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1671,6 +1671,13 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean pepPublishOptions() {
|
||||||
|
synchronized (XmppConnection.this.disco) {
|
||||||
|
ServiceDiscoveryResult info = disco.get(account.getJid().toBareJid());
|
||||||
|
return info != null && info.getFeatures().contains(Namespace.PUBSUB_PUBLISH_OPTIONS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean mam() {
|
public boolean mam() {
|
||||||
return hasDiscoFeature(account.getJid().toBareJid(), Namespace.MAM)
|
return hasDiscoFeature(account.getJid().toBareJid(), Namespace.MAM)
|
||||||
|| hasDiscoFeature(account.getJid().toBareJid(), Namespace.MAM_LEGACY);
|
|| hasDiscoFeature(account.getJid().toBareJid(), Namespace.MAM_LEGACY);
|
||||||
|
|
|
@ -39,13 +39,14 @@ public class Data extends Element {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void put(String name, String value) {
|
public Field put(String name, String value) {
|
||||||
Field field = getFieldByName(name);
|
Field field = getFieldByName(name);
|
||||||
if (field == null) {
|
if (field == null) {
|
||||||
field = new Field(name);
|
field = new Field(name);
|
||||||
this.addChild(field);
|
this.addChild(field);
|
||||||
}
|
}
|
||||||
field.setValue(value);
|
field.setValue(value);
|
||||||
|
return field;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void put(String name, Collection<String> values) {
|
public void put(String name, Collection<String> values) {
|
||||||
|
@ -91,7 +92,8 @@ public class Data extends Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFormType(String formType) {
|
public void setFormType(String formType) {
|
||||||
this.put(FORM_TYPE, formType);
|
Field field = this.put(FORM_TYPE, formType);
|
||||||
|
field.setAttribute("type","hidden");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFormType() {
|
public String getFormType() {
|
||||||
|
@ -108,4 +110,15 @@ public class Data extends Element {
|
||||||
return findChildContent("title");
|
return findChildContent("title");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Data create(String type, Bundle bundle) {
|
||||||
|
Data data = new Data();
|
||||||
|
data.setFormType(type);
|
||||||
|
data.setAttribute("type","submit");
|
||||||
|
for(String key : bundle.keySet()) {
|
||||||
|
data.put(key,bundle.getString(key));
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue