Search in sources :

Example 56 with IQ

use of org.xmpp.packet.IQ in project Openfire by igniterealtime.

the class MediaProxyService method processIQ.

private void processIQ(IQ iq) {
    IQ reply = IQ.createResultIQ(iq);
    Element childElement = iq.getChildElement();
    String namespace = childElement.getNamespaceURI();
    Element childElementCopy = iq.getChildElement().createCopy();
    reply.setChildElement(childElementCopy);
    if ("http://jabber.org/protocol/disco#info".equals(namespace)) {
        reply = XMPPServer.getInstance().getIQDiscoInfoHandler().handleIQ(iq);
        router.route(reply);
        return;
    } else if ("http://jabber.org/protocol/disco#items".equals(namespace)) {
        // a component
        reply = XMPPServer.getInstance().getIQDiscoItemsHandler().handleIQ(iq);
        router.route(reply);
        return;
    } else if (NAMESPACE.equals(namespace) && enabled) {
        Element candidateElement = childElementCopy.element("candidate");
        String sid = childElementCopy.attribute("sid").getValue() + "-" + iq.getFrom();
        if (candidateElement != null) {
            childElementCopy.remove(candidateElement);
            Element candidate = childElementCopy.addElement("candidate ");
            ProxyCandidate proxyCandidate = mediaProxy.addRelayAgent(sid, iq.getFrom().toString());
            Log.debug("MediaProxyService: " + sid);
            proxyCandidate.start();
            candidate.addAttribute("name", "voicechannel");
            candidate.addAttribute("ip", mediaProxy.getPublicIP());
            candidate.addAttribute("porta", String.valueOf(proxyCandidate.getLocalPortA()));
            candidate.addAttribute("portb", String.valueOf(proxyCandidate.getLocalPortB()));
            candidate.addAttribute("pass", proxyCandidate.getPass());
        } else {
            candidateElement = childElementCopy.element("relay");
            if (candidateElement != null) {
                MediaProxySession session = mediaProxy.getSession(sid);
                Log.debug("MediaProxyService: " + sid);
                if (session != null) {
                    Attribute pass = candidateElement.attribute("pass");
                    if (pass != null && pass.getValue().trim().equals(session.getPass().trim())) {
                        Attribute portA = candidateElement.attribute("porta");
                        Attribute portB = candidateElement.attribute("portb");
                        Attribute hostA = candidateElement.attribute("hosta");
                        Attribute hostB = candidateElement.attribute("hostb");
                        try {
                            if (hostA != null && portA != null) {
                                for (int i = 0; i < 2; i++) {
                                    session.sendFromPortA(hostB.getValue(), Integer.parseInt(portB.getValue()));
                                }
                            }
                        } catch (Exception e) {
                            Log.error(e.getMessage(), e);
                        }
                    } else {
                        reply.setError(PacketError.Condition.forbidden);
                    }
                }
                childElementCopy.remove(candidateElement);
            } else {
                candidateElement = childElementCopy.element("publicip");
                if (candidateElement != null) {
                    childElementCopy.remove(candidateElement);
                    Element publicIp = childElementCopy.addElement("publicip");
                    try {
                        String ip = sessionManager.getSession(iq.getFrom()).getHostAddress();
                        if (ip != null) {
                            publicIp.addAttribute("ip", ip);
                        }
                    } catch (UnknownHostException e) {
                        Log.error(e.getMessage(), e);
                    }
                } else {
                    childElementCopy.remove(candidateElement);
                    reply.setError(PacketError.Condition.forbidden);
                }
            }
        }
    } else {
        // Answer an error since the server can't handle the requested namespace
        reply.setError(PacketError.Condition.service_unavailable);
    }
    try {
        if (Log.isDebugEnabled()) {
            Log.debug("MediaProxyService: RETURNED:" + reply.toXML());
        }
        router.route(reply);
    } catch (Exception e) {
        Log.error(e.getMessage(), e);
    }
}
Also used : UnknownHostException(java.net.UnknownHostException) Attribute(org.dom4j.Attribute) Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ) PacketException(org.jivesoftware.openfire.PacketException) UnauthorizedException(org.jivesoftware.openfire.auth.UnauthorizedException) SocketException(java.net.SocketException) UnknownHostException(java.net.UnknownHostException)

Example 57 with IQ

use of org.xmpp.packet.IQ in project Openfire by igniterealtime.

the class LeafNode method sendPublishedItems.

/**
 * Sends an IQ result with the list of items published to the node. Item ID and payload
 * may be included in the result based on the node configuration.
 *
 * @param originalRequest the IQ packet sent by a subscriber (or anyone) to get the node items.
 * @param publishedItems the list of published items to send to the subscriber.
 * @param forceToIncludePayload true if the item payload should be include if one exists. When
 *        false the decision is up to the node.
 */
void sendPublishedItems(IQ originalRequest, List<PublishedItem> publishedItems, boolean forceToIncludePayload) {
    IQ result = IQ.createResultIQ(originalRequest);
    Element pubsubElem = result.setChildElement("pubsub", "http://jabber.org/protocol/pubsub");
    Element items = pubsubElem.addElement("items");
    items.addAttribute("node", nodeID);
    for (PublishedItem publishedItem : publishedItems) {
        Element item = items.addElement("item");
        if (isItemRequired()) {
            item.addAttribute("id", publishedItem.getID());
        }
        if ((forceToIncludePayload || isPayloadDelivered()) && publishedItem.getPayload() != null) {
            item.add(publishedItem.getPayload().createCopy());
        }
    }
    // Send the result
    getService().send(result);
}
Also used : Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ)

Example 58 with IQ

use of org.xmpp.packet.IQ in project Openfire by igniterealtime.

the class Node method createSubscription.

/**
 * Creates a new subscription and possibly a new affiliate if the owner of the subscription
 * does not have any existing affiliation with the node. The new subscription might require
 * to be authorized by a node owner to be active. If new subscriptions are required to be
 * configured before being active then the subscription state would be "unconfigured".<p>
 *
 * The originalIQ parameter may be {@code null} when using this API internally. When no
 * IQ packet was sent then no IQ result will be sent to the sender. The rest of the
 * functionality is the same.
 *
 * @param originalIQ the IQ packet sent by the entity to subscribe to the node or
 *        null when using this API internally.
 * @param owner the JID of the affiliate.
 * @param subscriber the JID where event notifications are going to be sent.
 * @param authorizationRequired true if the new subscriptions needs to be authorized by
 *        a node owner.
 * @param options the data form with the subscription configuration or null if subscriber
 *        didn't provide a configuration.
 */
public void createSubscription(IQ originalIQ, JID owner, JID subscriber, boolean authorizationRequired, DataForm options) {
    // Create a new affiliation if required
    if (getAffiliate(owner) == null) {
        addNoneAffiliation(owner);
    }
    // Figure out subscription status
    NodeSubscription.State subState = NodeSubscription.State.subscribed;
    if (isSubscriptionConfigurationRequired()) {
        // User has to configure the subscription to make it active
        subState = NodeSubscription.State.unconfigured;
    } else if (authorizationRequired && !isAdmin(owner)) {
        // Node owner needs to authorize subscription request so status is pending
        subState = NodeSubscription.State.pending;
    }
    // Generate a subscription ID (override even if one was sent by the client)
    String id = StringUtils.randomString(40);
    // Create new subscription
    NodeSubscription subscription = new NodeSubscription(this, owner, subscriber, subState, id);
    // Configure the subscription with the specified configuration (if any)
    if (options != null) {
        subscription.configure(options);
    }
    if (subscription.isAuthorizationPending()) {
        final Set<NodeSubscription> existing = new HashSet<>();
        // potentially null
        existing.add(subscriptionsByJID.get(subscription.getJID().toString()));
        existing.addAll(subscriptionsByID.values().stream().filter(s -> s.getJID().equals(subscription.getJID())).collect(Collectors.toSet()));
        if (existing.stream().anyMatch(s -> s != null && s.isAuthorizationPending())) {
            // This node already has a pending subscription for this JID. The XEP forbids this.
            if (originalIQ != null) {
                final IQ response = IQ.createResultIQ(originalIQ);
                response.setError(PacketError.Condition.not_authorized);
                response.getError().getElement().addElement("pending-subscription", "http://jabber.org/protocol/pubsub#errors");
                getService().send(response);
            }
            // Silently ignore if this was an internal API call.
            return;
        }
    }
    addSubscription(subscription);
    if (savedToDB) {
        // Add the new subscription to the database
        XMPPServer.getInstance().getPubSubModule().getPersistenceProvider().createSubscription(this, subscription);
    }
    if (originalIQ != null) {
        // Reply with subscription and affiliation status indicating if subscription
        // must be configured (only when subscription was made through an IQ packet)
        subscription.sendSubscriptionState(originalIQ);
    }
    // new subscription
    if (subscription.isAuthorizationPending()) {
        subscription.sendAuthorizationRequest();
    }
    // Update the other members with the new subscription
    CacheFactory.doClusterTask(new NewSubscriptionTask(subscription));
    // Send last published item (if node is leaf node and subscription status is ok)
    if (isSendItemSubscribe() && subscription.isActive()) {
        PublishedItem lastItem = getLastPublishedItem();
        if (lastItem != null) {
            subscription.sendLastPublishedItem(lastItem);
        }
    }
    // Check if we need to subscribe to the presence of the owner
    if (isPresenceBasedDelivery() && getSubscriptions(subscription.getOwner()).size() == 1) {
        if (subscription.getPresenceStates().isEmpty()) {
            // Subscribe to the owner's presence since the node is only sending events to
            // online subscribers and this is the first subscription of the user and the
            // subscription is not filtering notifications based on presence show values.
            getService().presenceSubscriptionRequired(this, owner);
        }
    }
}
Also used : IQ(org.xmpp.packet.IQ)

Example 59 with IQ

use of org.xmpp.packet.IQ in project Openfire by igniterealtime.

the class IQPEPHandler method createSubscriptionToPEPService.

/**
 * Generates and processes an IQ stanza that subscribes to a PEP service.
 *
 * @param pepService the PEP service of the owner.
 * @param subscriber the JID of the entity that is subscribing to the PEP service.
 * @param owner      the JID of the owner of the PEP service.
 */
private void createSubscriptionToPEPService(PEPService pepService, JID subscriber, JID owner) {
    // If `owner` has a PEP service, generate and process a pubsub subscription packet
    // that is equivalent to: (where 'from' field is JID of subscriber and 'to' field is JID of owner)
    // 
    // <iq type='set'
    // from='nurse@capulet.com/chamber'
    // to='juliet@capulet.com
    // id='collsub'>
    // <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    // <subscribe jid='nurse@capulet.com'/>
    // <options>
    // <x xmlns='jabber:x:data'>
    // <field var='FORM_TYPE' type='hidden'>
    // <value>http://jabber.org/protocol/pubsub#subscribe_options</value>
    // </field>
    // <field var='pubsub#subscription_type'>
    // <value>items</value>
    // </field>
    // <field var='pubsub#subscription_depth'>
    // <value>all</value>
    // </field>
    // </x>
    // </options>
    // </pubsub>
    // </iq>
    IQ subscriptionPacket = new IQ(IQ.Type.set);
    subscriptionPacket.setFrom(subscriber);
    subscriptionPacket.setTo(owner.toBareJID());
    Element pubsubElement = subscriptionPacket.setChildElement("pubsub", "http://jabber.org/protocol/pubsub");
    Element subscribeElement = pubsubElement.addElement("subscribe");
    subscribeElement.addAttribute("jid", subscriber.toBareJID());
    Element optionsElement = pubsubElement.addElement("options");
    Element xElement = optionsElement.addElement(QName.get("x", "jabber:x:data"));
    DataForm dataForm = new DataForm(xElement);
    FormField formField = dataForm.addField();
    formField.setVariable("FORM_TYPE");
    formField.setType(FormField.Type.hidden);
    formField.addValue("http://jabber.org/protocol/pubsub#subscribe_options");
    formField = dataForm.addField();
    formField.setType(FormField.Type.list_single);
    formField.setVariable("pubsub#subscription_type");
    formField.addValue("items");
    formField = dataForm.addField();
    formField.setType(FormField.Type.list_single);
    formField.setVariable("pubsub#subscription_depth");
    formField.addValue("all");
    pepServiceManager.process(pepService, subscriptionPacket);
}
Also used : Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ) DataForm(org.xmpp.forms.DataForm) FormField(org.xmpp.forms.FormField)

Example 60 with IQ

use of org.xmpp.packet.IQ in project Openfire by igniterealtime.

the class IQPEPHandler method handleIQSetToService.

/**
 * Process an IQ set stanza that was addressed to the service (rather than to a node/user).
 *
 * @param packet The stanza to process.
 * @return A response (can be null).
 */
private IQ handleIQSetToService(IQ packet) {
    final JID senderJID = packet.getFrom();
    final JID bareJidFrom = senderJID.asBareJID();
    packet = packet.createCopy();
    packet.setTo(bareJidFrom);
    // Only service local, registered users.
    if (!UserManager.getInstance().isRegisteredUser(senderJID, false)) {
        final IQ reply = IQ.createResultIQ(packet);
        reply.setChildElement(packet.getChildElement().createCopy());
        reply.setError(PacketError.Condition.not_allowed);
        return reply;
    }
    PEPService pepService = pepServiceManager.getPEPService(bareJidFrom);
    // If publishing a node, and the node doesn't exist, create it.
    final Element childElement = packet.getChildElement();
    final Element publishElement = childElement.element("publish");
    if (publishElement != null) {
        final String nodeID = publishElement.attributeValue("node");
        // TODO: Implement XEP-0084
        if (nodeID.startsWith("http://www.xmpp.org/extensions/xep-0084.html")) {
            IQ reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(PacketError.Condition.feature_not_implemented);
            return reply;
        }
        if (pepService.getNode(nodeID) == null) {
            // Create the node
            final JID creator = bareJidFrom;
            final DefaultNodeConfiguration defaultConfiguration = pepService.getDefaultNodeConfiguration(true);
            final LeafNode newNode = new LeafNode(pepService.getUniqueIdentifier(), pepService.getRootCollectionNode(), nodeID, creator, defaultConfiguration);
            final DataForm publishOptions = PubSubEngine.getPublishOptions(packet);
            if (publishOptions != null) {
                try {
                    newNode.configure(publishOptions);
                } catch (NotAcceptableException e) {
                    Log.warn("Unable to apply publish-options when creating a new PEP node {} for {}", nodeID, creator, e);
                }
            }
            newNode.addOwner(creator);
            newNode.saveToDB();
        }
    }
    // Process with PubSub as usual.
    pepServiceManager.process(pepService, packet);
    return null;
}
Also used : JID(org.xmpp.packet.JID) Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ) DataForm(org.xmpp.forms.DataForm)

Aggregations

IQ (org.xmpp.packet.IQ)208 Element (org.dom4j.Element)141 JID (org.xmpp.packet.JID)49 PacketError (org.xmpp.packet.PacketError)35 Presence (org.xmpp.packet.Presence)19 UserNotFoundException (org.jivesoftware.openfire.user.UserNotFoundException)18 Message (org.xmpp.packet.Message)17 UnauthorizedException (org.jivesoftware.openfire.auth.UnauthorizedException)16 ClientSession (org.jivesoftware.openfire.session.ClientSession)14 DataForm (org.xmpp.forms.DataForm)13 ArrayList (java.util.ArrayList)11 AgentNotFoundException (org.jivesoftware.xmpp.workgroup.AgentNotFoundException)10 Packet (org.xmpp.packet.Packet)10 PacketException (org.jivesoftware.openfire.PacketException)9 User (org.jivesoftware.openfire.user.User)8 List (java.util.List)7 PrivacyList (org.jivesoftware.openfire.privacy.PrivacyList)7 Iterator (java.util.Iterator)6 Test (org.junit.Test)6 FormField (org.xmpp.forms.FormField)6