use of org.xmpp.packet.IQ in project Openfire by igniterealtime.
the class IQMUCvCardHandler method handleIQ.
@Override
public IQ handleIQ(IQ packet) throws PacketException {
IQ result = IQ.createResultIQ(packet);
IQ.Type type = packet.getType();
if (type.equals(IQ.Type.set)) {
Log.debug("vCard update request received from: '{}', for: '{}'", packet.getFrom(), packet.getTo());
try {
String roomName = packet.getTo().getNode();
// If no TO was specified then return an error.
if (roomName == null) {
Log.debug("vCard update request from: '{}', for: '{}' is invalid: it does not refer to a specific room.", packet.getFrom(), packet.getTo());
result.setChildElement(packet.getChildElement().createCopy());
result.setError(PacketError.Condition.not_acceptable);
result.getError().setText("Request 'to' attribute has no node-part. The request should be addressed to a room of a MUC service.");
} else {
final Lock lock = mucService.getChatRoomLock(roomName);
lock.lock();
try {
final MUCRoom room = mucService.getChatRoom(roomName);
Log.debug("vCard update request from: '{}', for: '{}' relates to room: {}", packet.getFrom(), packet.getTo(), room);
if (room == null || !room.getOwners().contains(packet.getFrom().asBareJID())) {
Log.debug("vCard update request from: '{}', for: '{}' is invalid: room does not exist, or sender is not allowed to discover the room.", packet.getFrom(), packet.getTo());
result.setChildElement(packet.getChildElement().createCopy());
result.setError(PacketError.Condition.forbidden);
result.getError().setText("You are not an owner of this room.");
} else {
Element vcard = packet.getChildElement();
if (vcard != null) {
try {
VCardManager.getInstance().setVCard(room.getJID().toString(), vcard);
// This is what EJabberd does. Mimic it, for compatibility.
sendConfigChangeNotification(room);
// Mimic a client that broadcasts a vCard update. Converse seems to need this.
final String hash = calculatePhotoHash(vcard);
sendVCardUpdateNotification(room, hash);
Log.debug("vCard update request from: '{}', for: '{}' processed successfully.", packet.getFrom(), packet.getTo());
} catch (UnsupportedOperationException e) {
Log.debug("Entity '{}' tried to set VCard, but the configured VCard provider is read-only. An IQ error will be returned to sender.", packet.getFrom());
// VCards can include binary data. Let's not echo that back in the error.
// result.setChildElement( packet.getChildElement().createCopy() );
result.setError(PacketError.Condition.not_allowed);
// default to server locale.
Locale locale = JiveGlobals.getLocale();
final Session session = SessionManager.getInstance().getSession(result.getTo());
if (session != null && session.getLanguage() != null) {
// use client locale if one is available.
locale = session.getLanguage();
}
result.getError().setText(LocaleUtils.getLocalizedString("vcard.read_only", locale), locale.getLanguage());
}
}
}
// No need to ensure that other cluster nodes see the changes applied above, as this code does not apply changes.
// mucService.syncChatRoom(room);
} finally {
lock.unlock();
}
}
} catch (UserNotFoundException e) {
// VCards can include binary data. Let's not echo that back in the error.
// result.setChildElement( packet.getChildElement().createCopy() );
result.setError(PacketError.Condition.item_not_found);
} catch (Exception e) {
Log.error(e.getMessage(), e);
result.setError(PacketError.Condition.internal_server_error);
}
} else if (type.equals(IQ.Type.get)) {
Log.debug("vCard retrieve request received from: '{}', for: '{}'", packet.getFrom(), packet.getTo());
String roomName = packet.getTo().getNode();
// If no TO was specified then return an error.
if (roomName == null) {
Log.debug("vCard retrieve request from: '{}', for: '{}' is invalid: it does not refer to a specific room.", packet.getFrom(), packet.getTo());
result.setChildElement(packet.getChildElement().createCopy());
result.setError(PacketError.Condition.not_acceptable);
result.getError().setText("Request 'to' attribute has no node-part. The request should be addressed to a room of a MUC service.");
} else {
// By default return an empty vCard
result.setChildElement(RESPONSE_ELEMENT_NAME, NAMESPACE);
// Only try to get the vCard values of rooms that can be discovered
// Answer the room occupants as items if that info is publicly available
final Lock lock = mucService.getChatRoomLock(roomName);
lock.lock();
try {
final MUCRoom room = mucService.getChatRoom(roomName);
Log.debug("vCard retrieve request from: '{}', for: '{}' relates to room: {}", packet.getFrom(), packet.getTo(), room);
if (room != null && mucService.canDiscoverRoom(room, packet.getFrom())) {
VCardManager vManager = VCardManager.getInstance();
Element userVCard = vManager.getVCard(room.getJID().toString());
if (userVCard != null) {
// Check if the requester wants to ignore some vCard's fields
Element filter = packet.getChildElement().element(QName.get("filter", "vcard-temp-filter"));
if (filter != null) {
// Create a copy so we don't modify the original vCard
userVCard = userVCard.createCopy();
// Ignore fields requested by the user
for (Iterator<Element> toFilter = filter.elementIterator(); toFilter.hasNext(); ) {
Element field = toFilter.next();
Element fieldToRemove = userVCard.element(field.getName());
if (fieldToRemove != null) {
fieldToRemove.detach();
}
}
}
result.setChildElement(userVCard);
Log.debug("vCard retrieve request from: '{}', for: '{}' processed successfully.", packet.getFrom(), packet.getTo());
}
} else {
Log.debug("vCard retrieve request from: '{}', for: '{}' is invalid: room does not exist, or sender is not allowed to discover the room.", packet.getFrom(), packet.getTo());
result = IQ.createResultIQ(packet);
result.setChildElement(packet.getChildElement().createCopy());
result.setError(PacketError.Condition.item_not_found);
result.getError().setText("Request 'to' references a room that cannot be found (or is not discoverable by you).");
}
// No need to ensure that other cluster nodes see the changes applied above, as this code does not apply changes.
// mucService.syncChatRoom(room);
} finally {
lock.unlock();
}
}
} else {
// Ignore non-request IQs
return null;
}
return result;
}
use of org.xmpp.packet.IQ in project Openfire by igniterealtime.
the class IQAdminHandler method handleIQ.
/**
* Handles the IQ packet sent by an owner or admin of the room. Possible actions are:
* <ul>
* <li>Return the list of participants</li>
* <li>Return the list of moderators</li>
* <li>Return the list of members</li>
* <li>Return the list of outcasts</li>
* <li>Change user's affiliation to member</li>
* <li>Change user's affiliation to outcast</li>
* <li>Change user's affiliation to none</li>
* <li>Change occupant's affiliation to moderator</li>
* <li>Change occupant's affiliation to participant</li>
* <li>Change occupant's affiliation to visitor</li>
* <li>Kick occupants from the room</li>
* </ul>
*
* @param packet the IQ packet sent by an owner or admin of the room.
* @param role the role of the user that sent the request packet.
* @throws ForbiddenException If the user is not allowed to perform his request.
* @throws ConflictException If the desired room nickname is already reserved for the room or
* if the room was going to lose all of its owners.
* @throws NotAllowedException Thrown if trying to ban an owner or an administrator.
* @throws CannotBeInvitedException If the user being invited as a result of being added to a members-only room still does not have permission
*/
public void handleIQ(IQ packet, MUCRole role) throws ForbiddenException, ConflictException, NotAllowedException, CannotBeInvitedException {
IQ reply = IQ.createResultIQ(packet);
Element element = packet.getChildElement();
// Analyze the action to perform based on the included element
@SuppressWarnings("unchecked") List<Element> itemsList = element.elements("item");
if (!itemsList.isEmpty()) {
handleItemsElement(role, itemsList, reply);
} else {
// An unknown and possibly incorrect element was included in the query
// element so answer a BAD_REQUEST error
reply.setChildElement(packet.getChildElement().createCopy());
reply.setError(PacketError.Condition.bad_request);
}
if (reply.getTo() != null) {
// Send a reply only if the sender of the original packet was from a real JID. (i.e. not
// a packet generated locally)
XMPPServer.getInstance().getPacketRouter().route(reply);
}
}
use of org.xmpp.packet.IQ in project Openfire by igniterealtime.
the class MultiplexerPacketDeliverer method handleUnprocessedPacket.
private void handleUnprocessedPacket(Packet packet) {
if (!ClientConnectionHandler.BACKUP_PACKET_DELIVERY_ENABLED.getValue()) {
Log.trace("Discarding packet that was due to be delivered on closed connection {}, for which no other multiplex connections are available, and no client backup deliverer was configured.", this);
return;
}
if (packet instanceof Message) {
messageStrategy.storeOffline((Message) packet);
} else if (packet instanceof Presence) {
// presence packets are dropped silently
// dropPacket(packet);
} else if (packet instanceof IQ) {
IQ iq = (IQ) packet;
// Check if we need to unwrap the packet
Element child = iq.getChildElement();
if (child != null && "session".equals(child.getName()) && "http://jabber.org/protocol/connectionmanager".equals(child.getNamespacePrefix())) {
Element send = child.element("send");
if (send != null) {
// Unwrap packet
Element wrappedElement = (Element) send.elements().get(0);
if ("message".equals(wrappedElement.getName())) {
handleUnprocessedPacket(new Message(wrappedElement));
}
}
} else {
// IQ packets are logged but dropped
Log.warn(LocaleUtils.getLocalizedString("admin.error.routing") + "\n" + packet.toString());
}
}
}
use of org.xmpp.packet.IQ in project Openfire by igniterealtime.
the class MultiplexerPacketHandler method handle.
/**
* Process IQ packet sent by a connection manager indicating that a new session has
* been created, should be closed or that a packet was failed to be delivered.
*
* @param packet the IQ packet.
*/
public void handle(Packet packet) {
if (packet instanceof IQ) {
IQ iq = (IQ) packet;
if (iq.getType() == IQ.Type.result) {
// Do nothing with result packets
} else if (iq.getType() == IQ.Type.error) {
// Log the IQ error packet that the connection manager failed to process
Log.warn("Connection Manager failed to process IQ packet: " + packet.toXML());
} else if (iq.getType() == IQ.Type.set) {
Element child = iq.getChildElement();
String streamIDValue = child.attributeValue("id");
if (streamIDValue == null) {
// No stream ID was included so return a bad_request error
Element extraError = DocumentHelper.createElement(QName.get("id-required", "http://jabber.org/protocol/connectionmanager#errors"));
sendErrorPacket(iq, PacketError.Condition.bad_request, extraError);
} else if ("session".equals(child.getName())) {
StreamID streamID = BasicStreamIDFactory.createStreamID(streamIDValue);
Element create = child.element("create");
if (create != null) {
// Get the InetAddress of the client
Element hostElement = create.element("host");
String hostName = hostElement != null ? hostElement.attributeValue("name") : null;
String hostAddress = hostElement != null ? hostElement.attributeValue("address") : null;
// Connection Manager wants to create a Client Session
boolean created = multiplexerManager.createClientSession(connectionManagerDomain, streamID, hostName, hostAddress);
if (created) {
sendResultPacket(iq);
} else {
// Send error to CM. The CM should close the new-born connection
sendErrorPacket(iq, PacketError.Condition.not_allowed, null);
}
} else {
ClientSession session = multiplexerManager.getClientSession(connectionManagerDomain, streamID);
if (session == null) {
// Specified Client Session does not exist
sendErrorPacket(iq, PacketError.Condition.item_not_found, null);
} else if (child.element("close") != null) {
// Connection Manager wants to close a Client Session
multiplexerManager.closeClientSession(connectionManagerDomain, streamID);
sendResultPacket(iq);
} else if (child.element("failed") != null) {
// Connection Manager failed to deliver a message
// Connection Manager wrapped a packet from a Client Session.
List wrappedElements = child.element("failed").elements();
if (wrappedElements.size() != 1) {
// Wrapper element is wrapping 0 or many items
Element extraError = DocumentHelper.createElement(QName.get("invalid-payload", "http://jabber.org/protocol/connectionmanager#errors"));
sendErrorPacket(iq, PacketError.Condition.bad_request, extraError);
} else {
Element wrappedElement = (Element) wrappedElements.get(0);
String tag = wrappedElement.getName();
if ("message".equals(tag)) {
XMPPServer.getInstance().getOfflineMessageStrategy().storeOffline(new Message(wrappedElement));
sendResultPacket(iq);
} else {
Element extraError = DocumentHelper.createElement(QName.get("unknown-stanza", "http://jabber.org/protocol/connectionmanager#errors"));
sendErrorPacket(iq, PacketError.Condition.bad_request, extraError);
}
}
} else {
// Unknown IQ packet received so return error to sender
sendErrorPacket(iq, PacketError.Condition.bad_request, null);
}
}
} else {
// Unknown IQ packet received so return error to sender
sendErrorPacket(iq, PacketError.Condition.bad_request, null);
}
} else {
// Unknown IQ packet received so return error to sender
sendErrorPacket(iq, PacketError.Condition.bad_request, null);
}
}
}
use of org.xmpp.packet.IQ in project Openfire by igniterealtime.
the class ComponentStanzaHandler method processIQ.
@Override
protected void processIQ(IQ packet) throws UnauthorizedException {
if (session.getStatus() != Session.STATUS_AUTHENTICATED) {
// Session is not authenticated so return error
IQ reply = new IQ();
reply.setChildElement(packet.getChildElement().createCopy());
reply.setID(packet.getID());
reply.setTo(packet.getFrom());
reply.setFrom(packet.getTo());
reply.setError(PacketError.Condition.not_authorized);
session.process(reply);
return;
}
// Keep track of the component that sent an IQ get/set
if (packet.getType() == IQ.Type.get || packet.getType() == IQ.Type.set) {
// Handle subsequent bind packets
LocalComponentSession componentSession = (LocalComponentSession) session;
// Get the external component of this session
LocalComponentSession.LocalExternalComponent component = (LocalComponentSession.LocalExternalComponent) componentSession.getExternalComponent();
component.track(packet);
}
super.processIQ(packet);
}
Aggregations