diff options
author | steckbrief <steckbrief@chefmail.de> | 2017-08-07 12:57:57 +0200 |
---|---|---|
committer | steckbrief <steckbrief@chefmail.de> | 2017-08-07 12:57:57 +0200 |
commit | a892bb6f1685b84b74ba37e5a6a24ee8fb45eee7 (patch) | |
tree | f6d8036841f961dd987c2fb48e41983b327be049 /src/main/java/de/thedevstack/conversationsplus/xmpp/disco | |
parent | be1992ce897d3b0551e545646a3e0f45cc6dd8c2 (diff) |
Simplifying introduction of new XEP implementations, implements FS#250 and FS#251 (Privacy and Security settings), refactoring of location of some interfaces
Diffstat (limited to '')
6 files changed, 223 insertions, 0 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/FeatureRegistry.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/FeatureRegistry.java new file mode 100644 index 00000000..1c266545 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/FeatureRegistry.java @@ -0,0 +1,90 @@ +package de.thedevstack.conversationsplus.xmpp.disco; + +import android.util.Base64; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import de.thedevstack.conversationsplus.ConversationsPlusApplication; +import de.thedevstack.conversationsplus.crypto.axolotl.AxolotlService; +import de.thedevstack.conversationsplus.xmpp.Xep; +import de.thedevstack.conversationsplus.xmpp.chatstate.ChatState; +import de.tzur.conversations.Settings; + +/** + */ +public final class FeatureRegistry { + public static final String IDENTITY_TYPE = "phone"; + + private static final String[] LEGACY_FEATURES = { + "urn:xmpp:jingle:1", + "urn:xmpp:jingle:apps:file-transfer:3", + "urn:xmpp:jingle:transports:s5b:1", + "urn:xmpp:jingle:transports:ibb:1", + "http://jabber.org/protocol/muc", + "jabber:x:conference", + "http://jabber.org/protocol/caps", + "http://jabber.org/protocol/disco#info", + "urn:xmpp:avatar:metadata+notify", + "http://jabber.org/protocol/nick+notify", + ChatState.NAMESPACE, + AxolotlService.PEP_DEVICE_LIST+"+notify"}; + private static final String[] LEGACY_MESSAGE_CONFIRMATION_FEATURES = { + "urn:xmpp:chat-markers:0", + "urn:xmpp:receipts" + }; + private final List<String> features = new ArrayList<>(); + private static final FeatureRegistry INSTANCE = new FeatureRegistry(); + + public static void add(String featureNamespace) { + if (null != featureNamespace) { + INSTANCE.features.add(featureNamespace); + } + } + + public static void remove(String featureNamespace) { + if (null != featureNamespace && INSTANCE.features.contains(featureNamespace)) { + INSTANCE.features.remove(featureNamespace); + } + } + public static void add(Xep xep) { + add(xep.featureNamespace()); + } + + public static void remove(Xep xep) { + remove(xep.featureNamespace()); + } + + public static List<String> getFeatures() { + Collections.sort(INSTANCE.features); + return INSTANCE.features; + } + + public static String getCapHash() { + StringBuilder s = new StringBuilder(); + s.append("client/" + IDENTITY_TYPE + "//" + ConversationsPlusApplication.getNameAndVersion() + "<"); + MessageDigest md; + try { + md = MessageDigest.getInstance("SHA-1"); + } catch (NoSuchAlgorithmException e) { + return null; + } + + for (String feature : getFeatures()) { + s.append(feature + "<"); + } + byte[] sha1 = md.digest(s.toString().getBytes()); + return new String(Base64.encode(sha1, Base64.DEFAULT)); + } + + private FeatureRegistry() { + this.features.addAll(Arrays.asList(LEGACY_FEATURES)); + if (Settings.CONFIRM_MESSAGE_RECEIVED) { + this.features.addAll(Arrays.asList(LEGACY_MESSAGE_CONFIRMATION_FEATURES)); + } + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscovery.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscovery.java new file mode 100644 index 00000000..59a4212b --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscovery.java @@ -0,0 +1,8 @@ +package de.thedevstack.conversationsplus.xmpp.disco; + +/** + */ +public interface ServiceDiscovery { + String NAMESPACE = "http://jabber.org/protocol/disco#info"; + String ELEMENT = "query"; +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryIqPacketGenerator.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryIqPacketGenerator.java new file mode 100644 index 00000000..8e1fc075 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryIqPacketGenerator.java @@ -0,0 +1,38 @@ +package de.thedevstack.conversationsplus.xmpp.disco; + +import de.thedevstack.conversationsplus.ConversationsPlusApplication; +import de.thedevstack.conversationsplus.xml.Element; +import de.thedevstack.conversationsplus.xmpp.jid.Jid; +import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket; +import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacketGenerator; + +/** + */ +public class ServiceDiscoveryIqPacketGenerator { + + public static IqPacket generateRequest(Jid jid) { + IqPacket request = IqPacketGenerator.generateIqGetPacket(); + request.setTo(jid); + request.query(ServiceDiscovery.NAMESPACE); + + return request; + } + + public static IqPacket generateResponse(IqPacket packet) { + IqPacket responsePacket = IqPacketGenerator.generateIqResultPacket(); + responsePacket.setTo(packet.getFrom()); + responsePacket.setId(packet.getId()); + + Element query = responsePacket.addChild(ServiceDiscovery.ELEMENT, ServiceDiscovery.NAMESPACE); + query.setAttribute("node", packet.query().getAttribute("node")); + final Element identity = query.addChild("identity"); + identity.setAttribute("category", "client"); + identity.setAttribute("type", FeatureRegistry.IDENTITY_TYPE); + identity.setAttribute("name", ConversationsPlusApplication.getNameAndVersion()); + for (final String feature : FeatureRegistry.getFeatures()) { + query.addChild("feature").setAttribute("var", feature); + } + + return responsePacket; + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryIqPacketHandler.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryIqPacketHandler.java new file mode 100644 index 00000000..6f1b0676 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryIqPacketHandler.java @@ -0,0 +1,21 @@ +package de.thedevstack.conversationsplus.xmpp.disco; + +import de.thedevstack.conversationsplus.entities.Account; +import de.thedevstack.conversationsplus.utils.XmppSendUtil; +import de.thedevstack.conversationsplus.xmpp.IqPacketHandler; +import de.thedevstack.conversationsplus.xmpp.exceptions.IqPacketErrorException; +import de.thedevstack.conversationsplus.xmpp.exceptions.NotAllowedIqException; +import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket; + +/** + */ +public class ServiceDiscoveryIqPacketHandler implements IqPacketHandler { + @Override + public void handleIqPacket(Account account, IqPacket packet) throws IqPacketErrorException { + if (packet.getType() == IqPacket.TYPE.GET) { + XmppSendUtil.sendIqPacket(account, ServiceDiscoveryIqPacketGenerator.generateResponse(packet)); + } else { + throw new NotAllowedIqException(packet, "only type=get allowed for processing an service discovery (XEP-0030)"); + } + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryIqPacketParser.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryIqPacketParser.java new file mode 100644 index 00000000..0ea0d752 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryIqPacketParser.java @@ -0,0 +1,15 @@ +package de.thedevstack.conversationsplus.xmpp.disco; + +import de.thedevstack.conversationsplus.entities.ServiceDiscoveryResult; +import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket; + +/** + */ +public class ServiceDiscoveryIqPacketParser { + public static ServiceDiscoveryResult parse(IqPacket packet) { + if (packet.getType() == IqPacket.TYPE.RESULT) { + return new ServiceDiscoveryResult(packet); + } + return null; + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryXep.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryXep.java new file mode 100644 index 00000000..6a21c71b --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryXep.java @@ -0,0 +1,51 @@ +package de.thedevstack.conversationsplus.xmpp.disco; + +import de.thedevstack.conversationsplus.xmpp.AbstractXep; +import de.thedevstack.conversationsplus.xmpp.IqPacketHandler; + +/** + */ +public class ServiceDiscoveryXep extends AbstractXep { + public ServiceDiscoveryXep() { + super(); + } + + public ServiceDiscoveryXep(boolean enabled) { + super(enabled); + } + + @Override + public String xepNumber() { + return "0030"; + } + + @Override + public String shortName() { + return "disco"; + } + + @Override + public String name() { + return "Service Discovery"; + } + + @Override + public String namespace() { + return ServiceDiscovery.NAMESPACE; + } + + @Override + public String featureNamespace() { + return ServiceDiscovery.NAMESPACE; + } + + @Override + public String elementName() { + return ServiceDiscovery.ELEMENT; + } + + @Override + public IqPacketHandler handler() { + return new ServiceDiscoveryIqPacketHandler(); + } +} |