public void interceptPacket(Packet packet, Session session, boolean incoming, boolean processed) throws PacketRejectedException { if (!processed && packet instanceof IQ && !incoming) { // Check for the Bookmark Storage element and hand off to the Bookmark engine. IQ iq = (IQ) packet; Element childElement = iq.getChildElement(); if (childElement == null || iq.getType() != IQ.Type.result) { return; } String namespace = childElement.getNamespaceURI(); if ("jabber:iq:private".equals(namespace)) { // In private data, when a user is attempting to retrieve bookmark // information, there will be a storage:bookmarks namespace. Element storageElement = childElement.element("storage"); if (storageElement == null) { return; } namespace = storageElement.getNamespaceURI(); if ("storage:bookmarks".equals(namespace)) { // Append Server defined bookmarks for user. JID toJID = iq.getTo(); addBookmarks(toJID, storageElement); } } } }
private void processIQ(IQ iq) { long start = System.currentTimeMillis(); Element childElement = iq.getChildElement(); String namespace = childElement.getNamespaceURI(); // 构造返回dom IQ reply = IQ.createResultIQ(iq); Element childElementCopy = childElement.createCopy(); reply.setChildElement(childElementCopy); if (XConstants.PROTOCOL_DISCO_INFO.equals(namespace)) { generateDisco(childElementCopy); // 构造disco反馈信息 if (LOG.isInfoEnabled()) { LOG.info( "[spend time:{}ms],reqId: {},IRComponent服务发现,response:{}", System.currentTimeMillis() - start, iq.getID(), reply.toXML()); } } try { ComponentManagerFactory.getComponentManager().sendPacket(this, reply); } catch (Throwable t) { LOG.error( "[spend time:{}ms],reqId: {},IRComponent IQ处理异常! iq:{},replay:{}", System.currentTimeMillis() - start, iq.getID(), reply.toXML(), t); } }
public void interceptPacket(Packet packet, Session session, boolean incoming, boolean processed) throws PacketRejectedException { // We only want packets recieved by the server if (!processed && incoming && packet instanceof IQ) { IQ iq = (IQ) packet; Element childElement = iq.getChildElement(); if (childElement == null) { return; } String namespace = childElement.getNamespaceURI(); String profile = childElement.attributeValue("profile"); // Check that the SI is about file transfer and try creating a file transfer if (NAMESPACE_SI.equals(namespace) && NAMESPACE_SI_FILETRANSFER.equals(profile)) { // If this is a set, check the feature offer if (iq.getType().equals(IQ.Type.set)) { JID from = iq.getFrom(); JID to = iq.getTo(); FileTransfer transfer = createFileTransfer(from, to, childElement); try { if (transfer == null || !acceptIncomingFileTransferRequest(transfer)) { throw new PacketRejectedException(); } } catch (FileTransferRejectedException e) { throw new PacketRejectedException(e); } } } } }
/** * Sets an application-specific error condition. Optionally, a application-specific namespace can * be specified to define its own application-specific error . * * @param name the name of the application-specific error condition. * @param namespaceURI the namespace of the application. */ @SuppressWarnings("unchecked") public void setApplicationCondition(String name, String namespaceURI) { if (ERROR_NAMESPACE.equals(namespaceURI)) { throw new IllegalArgumentException(); } // TODO: Remove this dependency on getElement() Element applicationError = null; for (Iterator<Element> i = getElement().elementIterator(); i.hasNext(); ) { Element el = i.next(); if (!el.getNamespaceURI().equals(ERROR_NAMESPACE)) { applicationError = el; } } if (applicationError != null) { getElement().remove(applicationError); } // If name is null, clear the application condition. if (name == null) { return; } if (namespaceURI == null) { // Set fallback namespace (see XEP-0182) namespaceURI = "urn:xmpp:errors"; } set(name, null, namespaceURI); }
private IQ getIQ(Element doc) { Element query = doc.element("query"); if (query != null && "jabber:iq:roster".equals(query.getNamespaceURI())) { return new Roster(doc); } else { return new IQ(doc); } }
public static String setXPathNamespace(Element ele, String xpath) { // 进行命名空间处理 if (!StringUtils.isEmptyString(ele.getNamespaceURI())) { // 将xpath中增加命名空间 xpath = xpath.replaceAll(XPATH_NAMESPACE_REGEX, XPATH_REPLACE_NAMESPACE); } return xpath; }
/* 526: */ /* 527: */ protected void startElement(Element element, AttributesImpl namespaceAttributes) /* 528: */ throws SAXException /* 529: */ { /* 530:810 */ this.contentHandler.startElement( element.getNamespaceURI(), element.getName(), element.getQualifiedName(), createAttributes(element, namespaceAttributes)); /* 531: */ }
@SuppressWarnings("unchecked") @Test @Ignore public void testCanControlGatheredEntriesUsingRsm() throws Exception { NodeItem item1 = new NodeItemImpl(TEST_NODE_1, "node1:1", new Date(0), "<entry>item1</entry>"); NodeItem item2 = new NodeItemImpl(TEST_NODE_2, "node2:1", new Date(10), "<entry>item2</entry>"); NodeItem item3 = new NodeItemImpl(TEST_NODE_1, "node1:2", new Date(20), "<entry>item3</entry>"); NodeItem item4 = new NodeItemImpl(TEST_NODE_1, "node1:3", new Date(30), "<entry>item4</entry>"); ArrayList<NodeItem> results = new ArrayList<NodeItem>(); results.add(item1); results.add(item2); results.add(item3); results.add(item4); Mockito.when( channelManager.getUserFeedItems( Mockito.any(JID.class), Mockito.any(Date.class), Mockito.anyInt(), Mockito.any(GlobalItemID.class), Mockito.anyBoolean())) .thenReturn(new ClosableIteratorImpl<NodeItem>(results.iterator())); Mockito.when( channelManager.getCountUserFeedItems( Mockito.any(JID.class), Mockito.any(Date.class), Mockito.anyBoolean())) .thenReturn(results.size()); Element rsm = request.getElement().addElement("rsm"); rsm.addNamespace("", PubSubElementProcessorAbstract.NS_RSM); rsm.addElement("max").addText("2"); rsm.addElement("after").addText("node1:1"); userItemsGet.process(element, jid, request, null); IQ response = (IQ) queue.poll(); Assert.assertEquals(IQ.Type.result, response.getType()); Element pubsub = response.getChildElement(); Assert.assertEquals("pubsub", pubsub.getName()); Assert.assertEquals(JabberPubsub.NAMESPACE_URI, pubsub.getNamespaceURI()); List<Element> items = pubsub.elements("items"); Assert.assertEquals(2, items.size()); Assert.assertEquals(TEST_NODE_2, items.get(0).attributeValue("node")); Assert.assertEquals(TEST_NODE_1, items.get(1).attributeValue("node")); Assert.assertEquals(1, items.get(0).elements("item").size()); Assert.assertEquals(1, items.get(1).elements("item").size()); Element rsmResult = pubsub.element("set"); Assert.assertEquals("2", rsmResult.element("count").getText()); Assert.assertEquals("node2:1", rsmResult.element("first").getText()); Assert.assertEquals("node1:2", rsmResult.element("last").getText()); }
/** * Decide whether a message should be stored offline according to XEP-0160 and XEP-0334. * * @param message * @return <code>true</code> if the message should be stored offline, <code>false</code> * otherwise. */ static boolean shouldStoreMessage(final Message message) { // XEP-0334: Implement the <no-store/> hint to override offline storage if (message.getChildElement("no-store", "urn:xmpp:hints") != null) { return false; } switch (message.getType()) { case chat: // XEP-0160: Messages with a 'type' attribute whose value is "chat" SHOULD be stored // offline, with the exception of messages that contain only Chat State Notifications // (XEP-0085) [7] content // Iterate through the child elements to see if we can find anything that's not a chat state // notification or // real time text notification Iterator<?> it = message.getElement().elementIterator(); while (it.hasNext()) { Object item = it.next(); if (item instanceof Element) { Element el = (Element) item; if (Namespace.NO_NAMESPACE.equals(el.getNamespace())) { continue; } if (!el.getNamespaceURI().equals("http://jabber.org/protocol/chatstates") && !(el.getQName().equals(QName.get("rtt", "urn:xmpp:rtt:0")))) { return true; } } } return message.getBody() != null && !message.getBody().isEmpty(); case groupchat: case headline: // XEP-0160: "groupchat" message types SHOULD NOT be stored offline // XEP-0160: "headline" message types SHOULD NOT be stored offline return false; case error: // XEP-0160: "error" message types SHOULD NOT be stored offline, // although a server MAY store advanced message processing errors offline if (message.getChildElement("amp", "http://jabber.org/protocol/amp") == null) { return false; } break; default: // XEP-0160: Messages with a 'type' attribute whose value is "normal" (or messages with no // 'type' attribute) SHOULD be stored offline. break; } return true; }
public void process(IQ packet) throws UnauthorizedException, PacketException { // sanitize the input if (packet == null) { throw new IllegalArgumentException("Argument 'packet' cannot be null."); } final String xmlns; final Element child = (packet).getChildElement(); if (child != null) { xmlns = child.getNamespaceURI(); } else { xmlns = null; } if (xmlns == null) { // No namespace defined. Log.debug("Cannot process this stanza, as it has no namespace:" + packet.toXML()); final IQ error = IQ.createResultIQ(packet); error.setError(Condition.bad_request); parent.sendPacket(error); return; } // done sanitizing, start processing. final Element remove = packet.getChildElement().element("remove"); if (remove != null) { // User wants to unregister. =( // this.convinceNotToLeave() ... kidding. handleDeregister(packet); } else { // handle the request switch (packet.getType()) { case get: // client requests registration form getRegistrationForm(packet); break; case set: // client is providing (filled out) registration form setRegistrationForm(packet); break; default: // ignore result and error stanzas. break; } } }
/** * Processes packets that were sent to this service. Currently only packets that were sent from * registered components are being processed. In the future, we may also process packet of trusted * clients. Trusted clients may be able to execute ad-hoc commands such as adding or removing * components. * * @param packet the packet to process. */ @Override public void process(Packet packet) throws PacketException { List<Component> components = getComponents(packet.getFrom()); // Only process packets that were sent by registered components if (!components.isEmpty()) { if (packet instanceof IQ && IQ.Type.result == ((IQ) packet).getType()) { IQ iq = (IQ) packet; Element childElement = iq.getChildElement(); if (childElement != null) { String namespace = childElement.getNamespaceURI(); if ("http://jabber.org/protocol/disco#info".equals(namespace)) { // Add a disco item to the server for the component that supports disco Element identity = childElement.element("identity"); if (identity == null) { // Do nothing since there are no identities in the disco#info packet return; } try { XMPPServer.getInstance() .getIQDiscoItemsHandler() .addComponentItem(packet.getFrom().toBareJID(), identity.attributeValue("name")); for (Component component : components) { if (component instanceof ComponentSession.ExternalComponent) { ComponentSession.ExternalComponent externalComponent = (ComponentSession.ExternalComponent) component; externalComponent.setName(identity.attributeValue("name")); externalComponent.setType(identity.attributeValue("type")); externalComponent.setCategory(identity.attributeValue("category")); } } } catch (Exception e) { Log.error( "Error processing disco packet of components: " + components + " - " + packet.toXML(), e); } // Store the IQ disco#info returned by the component addComponentInfo(iq); // Notify listeners that a component answered the disco#info request notifyComponentInfo(iq); // Alert other cluster nodes CacheFactory.doClusterTask(new NotifyComponentInfo(iq)); } } } } }
protected static Element getChildElement(Element element, String namespace) { //noinspection unchecked List<Element> elements = element.elements(); if (elements.isEmpty()) { return null; } for (Element childElement : elements) { String childNamespace = childElement.getNamespaceURI(); if (namespace.equals(childNamespace)) { return childElement; } } return null; }
@SuppressWarnings("unchecked") @Test public void testOutgoingStanzaFormattedAsExpected() throws Exception { NodeItem item1 = new NodeItemImpl(TEST_NODE_1, "1", new Date(), "<entry>item1</entry>"); NodeItem item2 = new NodeItemImpl(TEST_NODE_2, "1", new Date(), "<entry>item2</entry>"); NodeItem item3 = new NodeItemImpl(TEST_NODE_1, "2", new Date(), "<entry>item3</entry>"); NodeItem item4 = new NodeItemImpl(TEST_NODE_1, "3", new Date(), "<entry>item4</entry>"); ArrayList<NodeItem> results = new ArrayList<NodeItem>(); results.add(item1); results.add(item2); results.add(item3); results.add(item4); Mockito.when( channelManager.getUserFeedItems( Mockito.any(JID.class), Mockito.any(Date.class), Mockito.anyInt(), Mockito.any(GlobalItemID.class), Mockito.anyBoolean())) .thenReturn(new ClosableIteratorImpl<NodeItem>(results.iterator())); userItemsGet.process(element, jid, request, null); IQ response = (IQ) queue.poll(); Assert.assertEquals(IQ.Type.result, response.getType()); Element pubsub = response.getChildElement(); Assert.assertEquals("pubsub", pubsub.getName()); Assert.assertEquals(JabberPubsub.NAMESPACE_URI, pubsub.getNamespaceURI()); List<Element> items = pubsub.elements("items"); Assert.assertEquals(3, items.size()); Assert.assertEquals(TEST_NODE_1, items.get(0).attributeValue("node")); Assert.assertEquals(TEST_NODE_2, items.get(1).attributeValue("node")); Assert.assertEquals(TEST_NODE_1, items.get(2).attributeValue("node")); Assert.assertEquals(1, items.get(0).elements("item").size()); Assert.assertEquals(2, items.get(2).elements("item").size()); }
@Test public void testNoUserItemsReturnsEmptyStanza() throws Exception { Mockito.when( channelManager.getUserFeedItems( Mockito.any(JID.class), Mockito.any(Date.class), Mockito.anyInt(), Mockito.any(GlobalItemID.class), Mockito.anyBoolean())) .thenReturn(new ClosableIteratorImpl<NodeItem>(new ArrayList<NodeItem>().iterator())); userItemsGet.process(element, jid, request, null); IQ response = (IQ) queue.poll(); Assert.assertEquals(IQ.Type.result, response.getType()); Element pubsub = response.getChildElement(); Assert.assertEquals("pubsub", pubsub.getName()); Assert.assertEquals(JabberPubsub.NAMESPACE_URI, pubsub.getNamespaceURI()); }
/** * Returns the error condition. * * @return the error condition. * @see Condition */ @SuppressWarnings("unchecked") public Condition getCondition() { // TODO: Remote this dependency on getElement() for (Iterator<Element> i = getElement().elementIterator(); i.hasNext(); ) { Element el = i.next(); if (el.getNamespaceURI().equals(ERROR_NAMESPACE) && !el.getName().equals("text")) { return Condition.fromXMPP(el.getName()); } } // Looking for XMPP condition failed. See if a legacy error code exists, // which can be mapped into an XMPP error condition. String code = attribute("code"); if (code != null) { try { return Condition.fromLegacyCode(Integer.parseInt(code)); } catch (Exception e) { // Ignore -- unable to map legacy code into a valid condition // so return null. } } return null; }
/** * Sets the error condition. * * @param condition the error condition. * @see Condition */ @SuppressWarnings("unchecked") public void setCondition(Condition condition) { if (condition == null) { throw new NullPointerException("Condition cannot be null"); } // Set the error code for legacy support. setAttribute("code", Integer.toString(condition.getLegacyCode())); // TODO: Remove this dependencies on getElement() Element conditionElement = null; for (Iterator<Element> i = getElement().elementIterator(); i.hasNext(); ) { Element el = i.next(); if (el.getNamespaceURI().equals(ERROR_NAMESPACE) && !el.getName().equals("text")) { conditionElement = el; } } if (conditionElement != null) { getElement().remove(conditionElement); } set(condition.toXMPP(), null, ERROR_NAMESPACE); }
/** * Handles a IQ-register 'set' request, which is to be interpreted as a request to create a new * registration. * * @param packet the IQ-register 'set' stanza. * @throws UnauthorizedException if the user isn't allowed to register. */ private void setRegistrationForm(IQ packet) throws UnauthorizedException { final JID from = packet.getFrom(); final boolean registered; Collection<Registration> registrations = RegistrationManager.getInstance().getRegistrations(from, parent.transportType); if (registrations.iterator().hasNext()) { registered = true; } else { registered = false; } if (!registered && !parent.permissionManager.hasAccess(from)) { // User does not have permission to register with transport. // We want to allow them to change settings if they are already // registered. throw new UnauthorizedException( LocaleUtils.getLocalizedString("gateway.base.registrationdeniedbyacls", "kraken")); } // Parse the input variables String username = null; String password = null; String nickname = null; try { if (packet.getChildElement().element("x") != null) { final DataForm form = new DataForm(packet.getChildElement().element("x")); final List<FormField> fields = form.getFields(); for (final FormField field : fields) { final String var = field.getVariable(); if (var.equals("username")) { username = field.getValues().get(0); } else if (var.equals("password")) { password = field.getValues().get(0); } else if (var.equals("nick")) { nickname = field.getValues().get(0); } } } } // TODO: This shouldn't be done by catching an Exception - check for the // existence of elements instead. If we insist doing this with an // exception handler, prevent catching a generic Exception (catch more // specific subclasses instead). catch (Exception ex) { // No with data form apparently Log.info("Most likely, no dataform was present " + "in the IQ-register request.", ex); } // input variables could also exist in the non-extended elements final Element userEl = packet.getChildElement().element("username"); final Element passEl = packet.getChildElement().element("password"); final Element nickEl = packet.getChildElement().element("nick"); if (userEl != null) { username = userEl.getTextTrim(); } if (passEl != null) { password = passEl.getTextTrim(); } if (nickEl != null) { nickname = nickEl.getTextTrim(); } username = (username == null || username.equals("")) ? null : username; password = (password == null || password.equals("")) ? null : password; nickname = (nickname == null || nickname.equals("")) ? null : nickname; // verify that we've got wat we need. if (username == null || (parent.isPasswordRequired() && password == null) || (parent.isNicknameRequired() && nickname == null)) { // Invalid information from stanza, lets yell. Log.info( "Cannot process IQ register request, as it " + "fails to provide all data that's required: " + packet.toXML()); final IQ result = IQ.createResultIQ(packet); result.setError(Condition.bad_request); parent.sendPacket(result); return; } // Check if the client supports our proprietary 'rosterless' mode. final boolean rosterlessMode; final Element x = packet.getChildElement().element("x"); if (x != null && x.getNamespaceURI() != null && x.getNamespaceURI().equals(NameSpace.IQ_GATEWAY_REGISTER)) { rosterlessMode = true; Log.info("Registering " + packet.getFrom() + " as " + username + " in rosterless mode."); } else { rosterlessMode = false; Log.info( "Registering " + packet.getFrom() + " as " + username + " (without making use of rosterless mode)."); } // Here's where the true magic lies: create the registration! try { addNewRegistration(from, username, password, nickname, rosterlessMode); registrations = RegistrationManager.getInstance().getRegistrations(from, parent.transportType); Registration registration = registrations.iterator().next(); TransportSession session = parent.registrationLoggedIn(registration, from, PresenceType.available, "", -1); session.setRegistrationPacket(packet); session.detachSession(); parent.getSessionManager().storeSession(from, session); // final IQ result = IQ.createResultIQ(packet); // I believe this shouldn't be included. Leaving it around just in // case. // Element response = // DocumentHelper.createElement(QName.get("query", IQ_REGISTER)); // result.setChildElement(response); // parent.sendPacket(result); } catch (UserNotFoundException e) { Log.warn( "Someone attempted to register with the gateway " + "who is not registered with the server: " + from); final IQ eresult = IQ.createResultIQ(packet); eresult.setError(Condition.forbidden); parent.sendPacket(eresult); final Message em = new Message(); em.setType(Message.Type.error); em.setTo(packet.getFrom()); em.setFrom(packet.getTo()); em.setBody(LocaleUtils.getLocalizedString("gateway.base.registrationdeniednoacct", "kraken")); parent.sendPacket(em); } catch (IllegalAccessException e) { Log.warn( "Someone who is not a user of this server " + "tried to register with the transport: " + from); final IQ eresult = IQ.createResultIQ(packet); eresult.setError(Condition.forbidden); parent.sendPacket(eresult); final Message em = new Message(); em.setType(Message.Type.error); em.setTo(packet.getFrom()); em.setFrom(packet.getTo()); em.setBody(LocaleUtils.getLocalizedString("gateway.base.registrationdeniedbyhost", "kraken")); parent.sendPacket(em); } catch (IllegalArgumentException e) { Log.warn( "Someone attempted to register with the " + "gateway with an invalid username: "******"gateway.base.registrationdeniedbadusername", "kraken")); parent.sendPacket(em); } }
/* 532: */ /* 533: */ protected void endElement(Element element) /* 534: */ throws SAXException /* 535: */ { /* 536:816 */ this.contentHandler.endElement( element.getNamespaceURI(), element.getName(), element.getQualifiedName()); /* 537: */ }