From 1e335d527b888963aa953542cfae866ade0d5867 Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Sun, 10 Jan 2016 16:25:26 -0500 Subject: [PATCH] Generate capHash from any discovery result --- .../entities/ServiceDiscoveryResult.java | 84 ++++++++++++++++++- 1 file changed, 80 insertions(+), 4 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/ServiceDiscoveryResult.java b/src/main/java/eu/siacs/conversations/entities/ServiceDiscoveryResult.java index 963464402..853e75aac 100644 --- a/src/main/java/eu/siacs/conversations/entities/ServiceDiscoveryResult.java +++ b/src/main/java/eu/siacs/conversations/entities/ServiceDiscoveryResult.java @@ -1,26 +1,41 @@ package eu.siacs.conversations.entities; -import java.util.List; +import android.content.ContentValues; +import android.util.Base64; +import java.io.UnsupportedEncodingException; +import java.lang.Comparable; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.stanzas.IqPacket; public class ServiceDiscoveryResult { - public static class Identity { + + protected static String blankNull(String s) { + return s == null ? "" : s; + } + + public static class Identity implements Comparable { protected final String category; protected final String type; + protected final String lang; protected final String name; - public Identity(final String category, final String type, final String name) { + public Identity(final String category, final String type, final String lang, final String name) { this.category = category; this.type = type; + this.lang = lang; this.name = name; } public Identity(final Element el) { this.category = el.getAttribute("category"); this.type = el.getAttribute("type"); + this.lang = el.getAttribute("xml:lang"); this.name = el.getAttribute("name"); } @@ -32,9 +47,29 @@ public class ServiceDiscoveryResult { return this.type; } + public String getLang() { + return this.lang; + } + public String getName() { return this.name; } + + public int compareTo(Object other) { + Identity o = (Identity)other; + int r = blankNull(this.getCategory()).compareTo(blankNull(o.getCategory())); + if(r == 0) { + r = blankNull(this.getType()).compareTo(blankNull(o.getType())); + } + if(r == 0) { + r = blankNull(this.getLang()).compareTo(blankNull(o.getLang())); + } + if(r == 0) { + r = blankNull(this.getName()).compareTo(blankNull(o.getName())); + } + + return r; + } } protected final List identities; @@ -58,7 +93,9 @@ public class ServiceDiscoveryResult { identities.add(id); } } else if (element.getName().equals("feature")) { - features.add(element.getAttribute("var")); + if (element.getAttribute("var") != null) { + features.add(element.getAttribute("var")); + } } } } @@ -81,4 +118,43 @@ public class ServiceDiscoveryResult { return false; } + + public byte[] getCapHash() { + StringBuilder s = new StringBuilder(); + + List identities = this.getIdentities(); + Collections.sort(identities); + + for(Identity id : identities) { + s.append( + blankNull(id.getCategory()) + "/" + + blankNull(id.getType()) + "/" + + blankNull(id.getLang()) + "/" + + blankNull(id.getName()) + "<" + ); + } + + List features = this.getFeatures(); + Collections.sort(features); + + for (String feature : features) { + s.append(feature + "<"); + } + + // TODO: data forms? + + MessageDigest md; + try { + md = MessageDigest.getInstance("SHA-1"); + } catch (NoSuchAlgorithmException e) { + return null; + } + + try { + return md.digest(s.toString().getBytes("UTF-8")); + } catch(UnsupportedEncodingException e) { + return null; + } + } + }