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.SerialSingleThreadExecutor; | ||||
| import eu.siacs.conversations.xml.Element; | ||||
| import eu.siacs.conversations.xml.Namespace; | ||||
| import eu.siacs.conversations.xmpp.OnAdvancedStreamFeaturesLoaded; | ||||
| import eu.siacs.conversations.xmpp.OnIqPacketReceived; | ||||
| import eu.siacs.conversations.xmpp.jid.InvalidJidException; | ||||
| @ -214,7 +215,6 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | ||||
| 			putDevicesForJid(account.getJid().toBareJid().toPreppedString(), deviceIds, store); | ||||
| 			for (String  address : store.getKnownAddresses()) { | ||||
| 				deviceIds = store.getSubDeviceSessions(address); | ||||
| 				Log.d(Config.LOGTAG,account.getJid().toBareJid()+" adding device ids for "+address+" "+deviceIds); | ||||
| 				putDevicesForJid(address, deviceIds, store); | ||||
| 			} | ||||
| 
 | ||||
| @ -437,16 +437,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | ||||
| 		} | ||||
| 		Set<Integer> deviceIds = new HashSet<>(); | ||||
| 		deviceIds.add(getOwnDeviceId()); | ||||
| 		IqPacket publish = mXmppConnectionService.getIqGenerator().publishDeviceIds(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); | ||||
| 				} | ||||
| 			} | ||||
| 		}); | ||||
| 		publishDeviceIdsAndRefineAccessModel(deviceIds); | ||||
| 	} | ||||
| 
 | ||||
| 	public void distrustFingerprint(final String fingerprint) { | ||||
| @ -513,17 +504,40 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | ||||
| 			numPublishTriesOnEmptyPep = 0; | ||||
| 		} | ||||
| 		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); | ||||
| 		mXmppConnectionService.sendIqPacket(account, publish, new OnIqPacketReceived() { | ||||
| 			@Override | ||||
| 			public void onIqPacketReceived(Account account, IqPacket packet) { | ||||
| 				ownPushPending.set(false); | ||||
| 				if (packet.getType() == IqPacket.TYPE.ERROR) { | ||||
| 					pepBroken = true; | ||||
| 					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); | ||||
| 				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); | ||||
| 					if (packet.getType() == IqPacket.TYPE.ERROR) { | ||||
| 						pepBroken = true; | ||||
| 						Log.d(Config.LOGTAG, getLogprefix(account) + "Error received while publishing own device id" + packet.findChild("error")); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		}); | ||||
| @ -683,32 +697,45 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | ||||
| 									 Set<PreKeyRecord> preKeyRecords, | ||||
| 									 final boolean announceAfter, | ||||
| 									 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( | ||||
| 				signedPreKeyRecord, axolotlStore.getIdentityKeyPair().getPublicKey(), | ||||
| 				preKeyRecords, getOwnDeviceId()); | ||||
| 				preKeyRecords, getOwnDeviceId(),publishOptions); | ||||
| 		Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + ": Bundle " + getOwnDeviceId() + " in PEP not current. Publishing..."); | ||||
| 		mXmppConnectionService.sendIqPacket(account, publish, new OnIqPacketReceived() { | ||||
| 			@Override | ||||
| 			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(); | ||||
| 					mXmppConnectionService.pushNodeConfiguration(account, node, PublishOptions.openAccess(), new XmppConnectionService.OnConfigurationPushed() { | ||||
| 					mXmppConnectionService.pushNodeConfiguration(account, node, publishOptions, new XmppConnectionService.OnConfigurationPushed() { | ||||
| 						@Override | ||||
| 						public void onPushSucceeded() { | ||||
| 							Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Successfully published bundle. "); | ||||
| 							if (wipe) { | ||||
| 								wipeOtherPepDevices(); | ||||
| 							} else if (announceAfter) { | ||||
| 								Log.d(Config.LOGTAG, getLogprefix(account) + "Announcing device " + getOwnDeviceId()); | ||||
| 								publishOwnDeviceIdIfNeeded(); | ||||
| 							} | ||||
| 							publishDeviceBundle(signedPreKeyRecord,preKeyRecords, announceAfter, wipe, false); | ||||
| 						} | ||||
| 
 | ||||
| 						@Override | ||||
| 						public void onPushFailed() { | ||||
| 							Log.d(Config.LOGTAG,"unable to change access model for pubsub node"); | ||||
| 							publishDeviceBundle(signedPreKeyRecord,preKeyRecords, announceAfter, wipe, false); | ||||
| 						} | ||||
| 					}); | ||||
| 				} if (packet.getType() == IqPacket.TYPE.RESULT) { | ||||
| 					Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Successfully published bundle. "); | ||||
| 					if (wipe) { | ||||
| 						wipeOtherPepDevices(); | ||||
| 					} else if (announceAfter) { | ||||
| 						Log.d(Config.LOGTAG, getLogprefix(account) + "Announcing device " + getOwnDeviceId()); | ||||
| 						publishOwnDeviceIdIfNeeded(); | ||||
| 					} | ||||
| 				} else if (packet.getType() == IqPacket.TYPE.ERROR) { | ||||
| 					pepBroken = true; | ||||
| 					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; | ||||
| 	} | ||||
| 
 | ||||
| 	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 Element pubsub = packet.addChild("pubsub", | ||||
| 				"http://jabber.org/protocol/pubsub"); | ||||
| 		final Element publish = pubsub.addChild("publish"); | ||||
| 		publish.setAttribute("node", node); | ||||
| 		publish.addChild(item); | ||||
| 		if (options != null) { | ||||
| 			final Element publishOptions = pubsub.addChild("publish-options"); | ||||
| 			publishOptions.addChild(Data.create(Namespace.PUBSUB_PUBLISH_OPTIONS, options)); | ||||
| 		} | ||||
| 		return packet; | ||||
| 	} | ||||
| 
 | ||||
| 	protected IqPacket publish(final String node, final Element item) { | ||||
| 		return publish(node,item,null); | ||||
| 	} | ||||
| 
 | ||||
| 	protected IqPacket retrieve(String node, Element item) { | ||||
| 		final IqPacket packet = new IqPacket(IqPacket.TYPE.GET); | ||||
| 		final Element pubsub = packet.addChild("pubsub", | ||||
| @ -184,7 +192,7 @@ public class IqGenerator extends AbstractGenerator { | ||||
| 		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 list = item.addChild("list", AxolotlService.PEP_PREFIX); | ||||
| 		for(Integer id:ids) { | ||||
| @ -192,11 +200,11 @@ public class IqGenerator extends AbstractGenerator { | ||||
| 			device.setAttribute("id", id); | ||||
| 			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, | ||||
| 	                               final Set<PreKeyRecord> preKeyRecords, final int deviceId) { | ||||
| 								   final Set<PreKeyRecord> preKeyRecords, final int deviceId, Bundle publishOptions) { | ||||
| 		final Element item = new Element("item"); | ||||
| 		final Element bundle = item.addChild("bundle", AxolotlService.PEP_PREFIX); | ||||
| 		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)); | ||||
| 		} | ||||
| 
 | ||||
| 		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) { | ||||
|  | ||||
| @ -13,4 +13,6 @@ public final class Namespace { | ||||
| 	public static final String OOB = "jabber:x:oob"; | ||||
| 	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 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() { | ||||
| 			return hasDiscoFeature(account.getJid().toBareJid(), Namespace.MAM) | ||||
| 					|| hasDiscoFeature(account.getJid().toBareJid(), Namespace.MAM_LEGACY); | ||||
|  | ||||
| @ -39,13 +39,14 @@ public class Data extends Element { | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
| 	public void put(String name, String value) { | ||||
| 	public Field put(String name, String value) { | ||||
| 		Field field = getFieldByName(name); | ||||
| 		if (field == null) { | ||||
| 			field = new Field(name); | ||||
| 			this.addChild(field); | ||||
| 		} | ||||
| 		field.setValue(value); | ||||
| 		return field; | ||||
| 	} | ||||
| 
 | ||||
| 	public void put(String name, Collection<String> values) { | ||||
| @ -91,7 +92,8 @@ public class Data extends Element { | ||||
| 	} | ||||
| 
 | ||||
| 	public void setFormType(String formType) { | ||||
| 		this.put(FORM_TYPE, formType); | ||||
| 		Field field = this.put(FORM_TYPE, formType); | ||||
| 		field.setAttribute("type","hidden"); | ||||
| 	} | ||||
| 
 | ||||
| 	public String getFormType() { | ||||
| @ -108,4 +110,15 @@ public class Data extends Element { | ||||
| 		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 New Issue
	
	Block a user
	 Daniel Gultsch
						Daniel Gultsch