Search in sources :

Example 6 with DataForm

use of org.jivesoftware.smackx.xdata.packet.DataForm in project Smack by igniterealtime.

the class EntityCapsManager method generateVerificationString.

/**
     * Generates a XEP-115 Verification String
     * 
     * @see <a href="http://xmpp.org/extensions/xep-0115.html#ver">XEP-115
     *      Verification String</a>
     * 
     * @param discoverInfo
     * @param hash
     *            the used hash function, if null, default hash will be used
     * @return The generated verification String or null if the hash is not
     *         supported
     */
protected static CapsVersionAndHash generateVerificationString(DiscoverInfo discoverInfo, String hash) {
    if (hash == null) {
        hash = DEFAULT_HASH;
    }
    // SUPPORTED_HASHES uses the format of MessageDigest, which is uppercase, e.g. "SHA-1" instead of "sha-1"
    MessageDigest md = SUPPORTED_HASHES.get(hash.toUpperCase(Locale.US));
    if (md == null)
        return null;
    // Then transform the hash to lowercase, as this value will be put on the wire within the caps element's hash
    // attribute. I'm not sure if the standard is case insensitive here, but let's assume that even it is, there could
    // be "broken" implementation in the wild, so we *always* transform to lowercase.
    hash = hash.toLowerCase(Locale.US);
    DataForm extendedInfo = DataForm.from(discoverInfo);
    // 1. Initialize an empty string S ('sb' in this method).
    // Use StringBuilder as we don't
    StringBuilder sb = new StringBuilder();
    // need thread-safe StringBuffer
    // 2. Sort the service discovery identities by category and then by
    // type and then by xml:lang
    // (if it exists), formatted as CATEGORY '/' [TYPE] '/' [LANG] '/'
    // [NAME]. Note that each slash is included even if the LANG or
    // NAME is not included (in accordance with XEP-0030, the category and
    // type MUST be included.
    SortedSet<DiscoverInfo.Identity> sortedIdentities = new TreeSet<DiscoverInfo.Identity>();
    for (DiscoverInfo.Identity i : discoverInfo.getIdentities()) sortedIdentities.add(i);
    // followed by the '<' character.
    for (DiscoverInfo.Identity identity : sortedIdentities) {
        sb.append(identity.getCategory());
        sb.append('/');
        sb.append(identity.getType());
        sb.append('/');
        sb.append(identity.getLanguage() == null ? "" : identity.getLanguage());
        sb.append('/');
        sb.append(identity.getName() == null ? "" : identity.getName());
        sb.append('<');
    }
    // 4. Sort the supported service discovery features.
    SortedSet<String> features = new TreeSet<String>();
    for (Feature f : discoverInfo.getFeatures()) features.add(f.getVar());
    // character
    for (String f : features) {
        sb.append(f);
        sb.append('<');
    }
    // see XEP-0115 5.4 step 3.6
    if (extendedInfo != null && extendedInfo.hasHiddenFormTypeField()) {
        synchronized (extendedInfo) {
            // 6. If the service discovery information response includes
            // XEP-0128 data forms, sort the forms by the FORM_TYPE (i.e.,
            // by the XML character data of the <value/> element).
            SortedSet<FormField> fs = new TreeSet<FormField>(new Comparator<FormField>() {

                @Override
                public int compare(FormField f1, FormField f2) {
                    return f1.getVariable().compareTo(f2.getVariable());
                }
            });
            FormField ft = null;
            for (FormField f : extendedInfo.getFields()) {
                if (!f.getVariable().equals("FORM_TYPE")) {
                    fs.add(f);
                } else {
                    ft = f;
                }
            }
            // Add FORM_TYPE values
            if (ft != null) {
                formFieldValuesToCaps(ft.getValues(), sb);
            }
            // followed by the '<' character.
            for (FormField f : fs) {
                sb.append(f.getVariable());
                sb.append('<');
                formFieldValuesToCaps(f.getValues(), sb);
            }
        }
    }
    // 8. Ensure that S is encoded according to the UTF-8 encoding (RFC
    // 3269).
    // 9. Compute the verification string by hashing S using the algorithm
    // specified in the 'hash' attribute (e.g., SHA-1 as defined in RFC
    // 3174).
    // The hashed data MUST be generated with binary output and
    // encoded using Base64 as specified in Section 4 of RFC 4648
    // (note: the Base64 output MUST NOT include whitespace and MUST set
    // padding bits to zero).
    byte[] bytes;
    try {
        bytes = sb.toString().getBytes(StringUtils.UTF8);
    } catch (UnsupportedEncodingException e) {
        throw new AssertionError(e);
    }
    byte[] digest;
    synchronized (md) {
        digest = md.digest(bytes);
    }
    String version = Base64.encodeToString(digest);
    return new CapsVersionAndHash(version, hash);
}
Also used : DiscoverInfo(org.jivesoftware.smackx.disco.packet.DiscoverInfo) UnsupportedEncodingException(java.io.UnsupportedEncodingException) Feature(org.jivesoftware.smackx.disco.packet.DiscoverInfo.Feature) Identity(org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity) TreeSet(java.util.TreeSet) DataForm(org.jivesoftware.smackx.xdata.packet.DataForm) MessageDigest(java.security.MessageDigest) Identity(org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity) FormField(org.jivesoftware.smackx.xdata.FormField)

Example 7 with DataForm

use of org.jivesoftware.smackx.xdata.packet.DataForm in project Smack by igniterealtime.

the class StreamNegotiator method createInitiationAccept.

/**
     * Creates the initiation acceptance stanza(/packet) to forward to the stream
     * initiator.
     *
     * @param streamInitiationOffer The offer from the stream initiator to connect for a stream.
     * @param namespaces            The namespace that relates to the accepted means of transfer.
     * @return The response to be forwarded to the initiator.
     */
protected static StreamInitiation createInitiationAccept(StreamInitiation streamInitiationOffer, String[] namespaces) {
    StreamInitiation response = new StreamInitiation();
    response.setTo(streamInitiationOffer.getFrom());
    response.setFrom(streamInitiationOffer.getTo());
    response.setType(IQ.Type.result);
    response.setStanzaId(streamInitiationOffer.getStanzaId());
    DataForm form = new DataForm(DataForm.Type.submit);
    FormField field = new FormField(FileTransferNegotiator.STREAM_DATA_FIELD_NAME);
    for (String namespace : namespaces) {
        field.addValue(namespace);
    }
    form.addField(field);
    response.setFeatureNegotiationForm(form);
    return response;
}
Also used : StreamInitiation(org.jivesoftware.smackx.si.packet.StreamInitiation) DataForm(org.jivesoftware.smackx.xdata.packet.DataForm) FormField(org.jivesoftware.smackx.xdata.FormField)

Example 8 with DataForm

use of org.jivesoftware.smackx.xdata.packet.DataForm in project Smack by igniterealtime.

the class DataFormProvider method parse.

@Override
public DataForm parse(XmlPullParser parser, int initialDepth) throws Exception {
    DataForm.Type dataFormType = DataForm.Type.fromString(parser.getAttributeValue("", "type"));
    DataForm dataForm = new DataForm(dataFormType);
    outerloop: while (true) {
        int eventType = parser.next();
        switch(eventType) {
            case XmlPullParser.START_TAG:
                String name = parser.getName();
                String namespace = parser.getNamespace();
                switch(name) {
                    case "instructions":
                        dataForm.addInstruction(parser.nextText());
                        break;
                    case "title":
                        dataForm.setTitle(parser.nextText());
                        break;
                    case "field":
                        dataForm.addField(parseField(parser));
                        break;
                    case "item":
                        dataForm.addItem(parseItem(parser));
                        break;
                    case "reported":
                        dataForm.setReportedData(parseReported(parser));
                        break;
                    // See XEP-133 Example 32 for a corner case where the data form contains this extension.
                    case RosterPacket.ELEMENT:
                        if (namespace.equals(RosterPacket.NAMESPACE)) {
                            dataForm.addExtensionElement(RosterPacketProvider.INSTANCE.parse(parser));
                        }
                        break;
                    // See XEP-141 Data Forms Layout
                    case DataLayout.ELEMENT:
                        if (namespace.equals(DataLayout.NAMESPACE)) {
                            dataForm.addExtensionElement(DataLayoutProvider.parse(parser));
                        }
                        break;
                }
                break;
            case XmlPullParser.END_TAG:
                if (parser.getDepth() == initialDepth) {
                    break outerloop;
                }
                break;
        }
    }
    return dataForm;
}
Also used : DataForm(org.jivesoftware.smackx.xdata.packet.DataForm)

Example 9 with DataForm

use of org.jivesoftware.smackx.xdata.packet.DataForm in project Smack by igniterealtime.

the class UserSearch method buildDataForm.

private static void buildDataForm(SimpleUserSearch search, String instructions, XmlPullParser parser) throws Exception {
    DataForm dataForm = new DataForm(DataForm.Type.form);
    boolean done = false;
    dataForm.setTitle("User Search");
    dataForm.addInstruction(instructions);
    while (!done) {
        int eventType = parser.next();
        if (eventType == XmlPullParser.START_TAG && !parser.getNamespace().equals("jabber:x:data")) {
            String name = parser.getName();
            FormField field = new FormField(name);
            // Handle hard coded values.
            if (name.equals("first")) {
                field.setLabel("First Name");
            } else if (name.equals("last")) {
                field.setLabel("Last Name");
            } else if (name.equals("email")) {
                field.setLabel("Email Address");
            } else if (name.equals("nick")) {
                field.setLabel("Nickname");
            }
            field.setType(FormField.Type.text_single);
            dataForm.addField(field);
        } else if (eventType == XmlPullParser.END_TAG) {
            if (parser.getName().equals("query")) {
                done = true;
            }
        } else if (eventType == XmlPullParser.START_TAG && parser.getNamespace().equals("jabber:x:data")) {
            PacketParserUtils.addExtensionElement(search, parser);
            done = true;
        }
    }
    if (search.getExtension("x", "jabber:x:data") == null) {
        search.addExtension(dataForm);
    }
}
Also used : DataForm(org.jivesoftware.smackx.xdata.packet.DataForm) FormField(org.jivesoftware.smackx.xdata.FormField)

Example 10 with DataForm

use of org.jivesoftware.smackx.xdata.packet.DataForm in project xabber-android by redsolution.

the class CapabilitiesManager method calculateString.

private String calculateString(DiscoverInfo discoverInfo) {
    StringBuilder s = new StringBuilder();
    SortedSet<String> identities = new TreeSet<>();
    for (DiscoverInfo.Identity identity : discoverInfo.getIdentities()) {
        StringBuilder builder = new StringBuilder();
        builder.append(identity.getCategory());
        builder.append("/");
        String type = identity.getType();
        if (type != null) {
            builder.append(type);
        }
        builder.append("/");
        String lang = identity.getLanguage();
        if (lang != null) {
            builder.append(lang);
        }
        builder.append("/");
        String name = identity.getName();
        if (name != null) {
            builder.append(name);
        }
        identities.add(builder.toString());
    }
    for (String identity : identities) {
        s.append(identity);
        s.append("<");
    }
    SortedSet<String> features = new TreeSet<>();
    for (DiscoverInfo.Feature feature : discoverInfo.getFeatures()) {
        features.add(feature.getVar());
    }
    for (String feature : features) {
        s.append(feature);
        s.append("<");
    }
    // Maps prepared value to FORM_TYPE key.
    // Extensions with equal FORM_TYPEs are not allowed.
    SortedMap<String, String> extendeds = new TreeMap<>();
    for (ExtensionElement packetExtension : discoverInfo.getExtensions()) {
        if (packetExtension instanceof DataForm) {
            DataForm dataForm = (DataForm) packetExtension;
            // Fields with equal var are allowed for fixed type.
            SortedSet<FormField> formFields = new TreeSet<>(new Comparator<FormField>() {

                @Override
                public int compare(FormField f1, FormField f2) {
                    // Var may not exists for fixed type.
                    String s1 = f1.getVariable();
                    String s2 = f2.getVariable();
                    return (s1 == null ? "" : s1).compareTo(s2 == null ? "" : s2);
                }
            });
            String formType = null;
            for (FormField formField : dataForm.getFields()) {
                if (FORM_TYPE.equals(formField.getVariable())) {
                    if (formField.getType() != FormField.Type.hidden) {
                        continue;
                    }
                    for (String value : formField.getValues()) {
                        formType = value;
                    }
                } else {
                    formFields.add(formField);
                }
            }
            if (formType == null) {
                continue;
            }
            StringBuilder builder = new StringBuilder();
            builder.append(formType);
            builder.append("<");
            for (FormField formField : formFields) {
                builder.append(formField.getVariable());
                builder.append("<");
                SortedSet<String> values = new TreeSet<>();
                for (String value : formField.getValues()) {
                    values.add(value);
                }
                for (String value : values) {
                    builder.append(value);
                    builder.append("<");
                }
            }
            extendeds.put(formType, builder.toString());
        }
    }
    for (Entry<String, String> extended : extendeds.entrySet()) {
        s.append(extended.getValue());
    }
    return s.toString();
}
Also used : DiscoverInfo(org.jivesoftware.smackx.disco.packet.DiscoverInfo) ExtensionElement(org.jivesoftware.smack.packet.ExtensionElement) TreeMap(java.util.TreeMap) TreeSet(java.util.TreeSet) DataForm(org.jivesoftware.smackx.xdata.packet.DataForm) FormField(org.jivesoftware.smackx.xdata.FormField)

Aggregations

DataForm (org.jivesoftware.smackx.xdata.packet.DataForm)65 FormField (org.jivesoftware.smackx.xdata.FormField)23 Test (org.junit.jupiter.api.Test)13 DiscoverInfo (org.jivesoftware.smackx.disco.packet.DiscoverInfo)12 Feature (com.xabber.xmpp.ssn.Feature)7 MamQueryIQ (org.jivesoftware.smackx.mam.element.MamQueryIQ)7 Date (java.util.Date)5 MamQueryArgs (org.jivesoftware.smackx.mam.MamManager.MamQueryArgs)5 OtrMode (com.xabber.xmpp.archive.OtrMode)4 LoggingValue (com.xabber.xmpp.ssn.LoggingValue)4 ArrayList (java.util.ArrayList)4 TreeSet (java.util.TreeSet)4 FillableForm (org.jivesoftware.smackx.xdata.form.FillableForm)4 LinkedList (java.util.LinkedList)3 IQ (org.jivesoftware.smack.packet.IQ)3 XmlPullParser (org.jivesoftware.smack.xml.XmlPullParser)3 Identity (org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity)3 DiscoverInfoBuilder (org.jivesoftware.smackx.disco.packet.DiscoverInfoBuilder)3 Form (org.jivesoftware.smackx.xdata.form.Form)3 DisclosureValue (com.xabber.xmpp.ssn.DisclosureValue)2