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);
}
}
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);
}
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);
}
}
}
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);
}
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;
}
Aggregations