Search in sources :

Example 1 with DiscoverInfo

use of org.jivesoftware.smackx.disco.packet.DiscoverInfo in project Smack by igniterealtime.

the class RoomInfoTest method validateRoomWithEmptyForm.

@Test
public void validateRoomWithEmptyForm() {
    DataForm dataForm = new DataForm(DataForm.Type.result);
    DiscoverInfo discoInfo = new DiscoverInfo();
    discoInfo.addExtension(dataForm);
    RoomInfo roomInfo = new RoomInfo(discoInfo);
    assertTrue(roomInfo.getDescription().isEmpty());
    assertTrue(roomInfo.getSubject().isEmpty());
    assertEquals(-1, roomInfo.getOccupantsCount());
}
Also used : DiscoverInfo(org.jivesoftware.smackx.disco.packet.DiscoverInfo) DataForm(org.jivesoftware.smackx.xdata.packet.DataForm) Test(org.junit.Test)

Example 2 with DiscoverInfo

use of org.jivesoftware.smackx.disco.packet.DiscoverInfo in project Smack by igniterealtime.

the class PingTest method checkSuccessfulDiscoRequest.

@Test
public void checkSuccessfulDiscoRequest() throws Exception {
    ThreadedDummyConnection con = getAuthentiactedDummyConnection();
    DiscoverInfo info = new DiscoverInfo();
    info.addFeature(Ping.NAMESPACE);
    //@formatter:off
    String reply = "<iq type='result' id='qrzSp-16' to='test@myserver.com'>" + "<query xmlns='http://jabber.org/protocol/disco#info'><identity category='client' type='pc' name='Pidgin'/>" + "<feature var='urn:xmpp:ping'/>" + "</query></iq>";
    //@formatter:on
    IQ discoReply = (IQ) PacketParserUtils.parseStanza(reply);
    con.addIQReply(discoReply);
    PingManager pinger = PingManager.getInstanceFor(con);
    boolean pingSupported = pinger.isPingSupported(DUMMY_AT_EXAMPLE_ORG);
    assertTrue(pingSupported);
}
Also used : ThreadedDummyConnection(org.jivesoftware.smack.ThreadedDummyConnection) DiscoverInfo(org.jivesoftware.smackx.disco.packet.DiscoverInfo) IQ(org.jivesoftware.smack.packet.IQ) Test(org.junit.Test)

Example 3 with DiscoverInfo

use of org.jivesoftware.smackx.disco.packet.DiscoverInfo 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 4 with DiscoverInfo

use of org.jivesoftware.smackx.disco.packet.DiscoverInfo in project Smack by igniterealtime.

the class DiscoverInfoProvider method parse.

@Override
public DiscoverInfo parse(XmlPullParser parser, int initialDepth) throws Exception {
    DiscoverInfo discoverInfo = new DiscoverInfo();
    boolean done = false;
    DiscoverInfo.Identity identity = null;
    String category = "";
    String identityName = "";
    String type = "";
    String variable = "";
    String lang = "";
    discoverInfo.setNode(parser.getAttributeValue("", "node"));
    while (!done) {
        int eventType = parser.next();
        if (eventType == XmlPullParser.START_TAG) {
            final String name = parser.getName();
            final String namespace = parser.getNamespace();
            if (namespace.equals(DiscoverInfo.NAMESPACE)) {
                switch(name) {
                    case "identity":
                        // Initialize the variables from the parsed XML
                        category = parser.getAttributeValue("", "category");
                        identityName = parser.getAttributeValue("", "name");
                        type = parser.getAttributeValue("", "type");
                        lang = parser.getAttributeValue(parser.getNamespace("xml"), "lang");
                        break;
                    case "feature":
                        // Initialize the variables from the parsed XML
                        variable = parser.getAttributeValue("", "var");
                        break;
                }
            } else // Otherwise, it must be a packet extension.
            {
                PacketParserUtils.addExtensionElement(discoverInfo, parser);
            }
        } else if (eventType == XmlPullParser.END_TAG) {
            if (parser.getName().equals("identity")) {
                // Create a new identity and add it to the discovered info.
                identity = new DiscoverInfo.Identity(category, type, identityName, lang);
                discoverInfo.addIdentity(identity);
            }
            if (parser.getName().equals("feature")) {
                // Create a new feature and add it to the discovered info.
                boolean notADuplicateFeature = discoverInfo.addFeature(variable);
                assert (notADuplicateFeature);
            }
            if (parser.getName().equals("query")) {
                done = true;
            }
        }
    }
    return discoverInfo;
}
Also used : DiscoverInfo(org.jivesoftware.smackx.disco.packet.DiscoverInfo)

Example 5 with DiscoverInfo

use of org.jivesoftware.smackx.disco.packet.DiscoverInfo in project Smack by igniterealtime.

the class ServiceDiscoveryManager method findServicesDiscoverInfo.

/**
     * Find all services under the users service that provide a given feature.
     * 
     * @param feature the feature to search for
     * @param stopOnFirst if true, stop searching after the first service was found
     * @param useCache if true, query a cache first to avoid network I/O
     * @return a possible empty list of services providing the given feature
     * @throws NoResponseException
     * @throws XMPPErrorException
     * @throws NotConnectedException
     * @throws InterruptedException 
     */
public List<DiscoverInfo> findServicesDiscoverInfo(String feature, boolean stopOnFirst, boolean useCache) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
    List<DiscoverInfo> serviceDiscoInfo = null;
    DomainBareJid serviceName = connection().getXMPPServiceDomain();
    if (useCache) {
        serviceDiscoInfo = services.lookup(feature);
        if (serviceDiscoInfo != null) {
            return serviceDiscoInfo;
        }
    }
    serviceDiscoInfo = new LinkedList<>();
    // Send the disco packet to the server itself
    DiscoverInfo info;
    try {
        info = discoverInfo(serviceName);
    } catch (XMPPErrorException e) {
        // Be extra robust here: Return the empty linked list and log this situation
        LOGGER.log(Level.WARNING, "Could not discover information about service", e);
        return serviceDiscoInfo;
    }
    // Check if the server supports the feature
    if (info.containsFeature(feature)) {
        serviceDiscoInfo.add(info);
        if (stopOnFirst) {
            if (useCache) {
                // Cache the discovered information
                services.put(feature, serviceDiscoInfo);
            }
            return serviceDiscoInfo;
        }
    }
    DiscoverItems items;
    try {
        // Get the disco items and send the disco packet to each server item
        items = discoverItems(serviceName);
    } catch (XMPPErrorException e) {
        LOGGER.log(Level.WARNING, "Could not discover items about service", e);
        return serviceDiscoInfo;
    }
    for (DiscoverItems.Item item : items.getItems()) {
        try {
            // TODO is it OK here in all cases to query without the node attribute?
            // MultipleRecipientManager queried initially also with the node attribute, but this
            // could be simply a fault instead of intentional.
            info = discoverInfo(item.getEntityID());
        } catch (XMPPErrorException | NoResponseException e) {
            // Don't throw this exceptions if one of the server's items fail
            LOGGER.log(Level.WARNING, "Exception while discovering info for feature " + feature + " of " + item.getEntityID() + " node: " + item.getNode(), e);
            continue;
        }
        if (info.containsFeature(feature)) {
            serviceDiscoInfo.add(info);
            //serviceAddresses.add(item.getEntityID().asDomainBareJid());
            if (stopOnFirst) {
                break;
            }
        }
    }
    if (useCache) {
        // Cache the discovered information
        services.put(feature, serviceDiscoInfo);
    }
    return serviceDiscoInfo;
}
Also used : DiscoverInfo(org.jivesoftware.smackx.disco.packet.DiscoverInfo) XMPPErrorException(org.jivesoftware.smack.XMPPException.XMPPErrorException) DiscoverItems(org.jivesoftware.smackx.disco.packet.DiscoverItems) NoResponseException(org.jivesoftware.smack.SmackException.NoResponseException) DomainBareJid(org.jxmpp.jid.DomainBareJid)

Aggregations

DiscoverInfo (org.jivesoftware.smackx.disco.packet.DiscoverInfo)53 Test (org.junit.Test)18 DiscoverItems (org.jivesoftware.smackx.disco.packet.DiscoverItems)12 XMPPErrorException (org.jivesoftware.smack.XMPPException.XMPPErrorException)11 Identity (org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity)11 IOException (java.io.IOException)8 SmackException (org.jivesoftware.smack.SmackException)8 XMPPException (org.jivesoftware.smack.XMPPException)8 Item (org.jivesoftware.smackx.disco.packet.DiscoverItems.Item)8 ConnectException (java.net.ConnectException)7 FeatureNotSupportedException (org.jivesoftware.smack.SmackException.FeatureNotSupportedException)7 ServiceDiscoveryManager (org.jivesoftware.smackx.disco.ServiceDiscoveryManager)7 DataForm (org.jivesoftware.smackx.xdata.packet.DataForm)7 XmppStringprepException (org.jxmpp.stringprep.XmppStringprepException)7 IQ (org.jivesoftware.smack.packet.IQ)6 Bytestream (org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream)6 FormField (org.jivesoftware.smackx.xdata.FormField)6 XMPPConnection (org.jivesoftware.smack.XMPPConnection)5 ArrayList (java.util.ArrayList)4 ThreadedDummyConnection (org.jivesoftware.smack.ThreadedDummyConnection)4