Java Code Examples for org.xmpp.packet.IQ#setError()

The following examples show how to use org.xmpp.packet.IQ#setError() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: IQAdminHandler.java    From Openfire with Apache License 2.0 6 votes vote down vote up
/**
 * 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)
        router.route(reply);
    }
}
 
Example 2
Source File: PubSubModule.java    From Openfire with Apache License 2.0 6 votes vote down vote up
@Override
public void process(Packet packet) {
    try {
        // Check if the packet is a disco request or a packet with namespace iq:register
        if (packet instanceof IQ) {
            if (engine.process(this, (IQ) packet) == null) {
                process((IQ) packet);
            }
        }
        else if (packet instanceof Presence) {
            engine.process(this, (Presence) packet);
        }
        else {
            engine.process(this, (Message) packet);
        }
    }
    catch (Exception e) {
        Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
        if (packet instanceof IQ) {
            // Send internal server error
            IQ reply = IQ.createResultIQ((IQ) packet);
            reply.setError(PacketError.Condition.internal_server_error);
            send(reply);
        }
    }
}
 
Example 3
Source File: ComponentStanzaHandler.java    From Openfire with Apache License 2.0 6 votes vote down vote up
@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);
}
 
Example 4
Source File: MultiplexerStanzaHandler.java    From Openfire with Apache License 2.0 6 votes vote down vote up
@Override
protected void processIQ(final IQ packet) {
    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;
    }
    // Process the packet
    packetHandler.handle(packet);
}
 
Example 5
Source File: IQSharedGroupHandler.java    From Openfire with Apache License 2.0 6 votes vote down vote up
@Override
public IQ handleIQ(IQ packet) throws UnauthorizedException {
    IQ result = IQ.createResultIQ(packet);
    String username = packet.getFrom().getNode();
    if (!serverName.equals(packet.getFrom().getDomain()) || username == null) {
        // Users of remote servers are not allowed to get their "shared groups". Users of
        // remote servers cannot have shared groups in this server.
        // Besides, anonymous users do not belong to shared groups so answer an error
        result.setChildElement(packet.getChildElement().createCopy());
        result.setError(PacketError.Condition.not_allowed);
        return result;
    }

    Collection<Group> groups = rosterManager.getSharedGroups(username);
    Element sharedGroups = result.setChildElement("sharedgroup",
            "http://www.jivesoftware.org/protocol/sharedgroup");
    for (Group sharedGroup : groups) {
        String displayName = sharedGroup.getProperties().get("sharedRoster.displayName");
        if (displayName != null) {
            sharedGroups.addElement("group").setText(displayName);
        }
    }
    return result;
}
 
Example 6
Source File: LocationHandler.java    From openfireLBS with Apache License 2.0 6 votes vote down vote up
private IQ updateLocation(IQ packet) {
	IQ reply = IQ.createResultIQ(packet);

	Element iq = packet.getChildElement();
	JID from = packet.getFrom();
	String username = from.getNode();

	Element item = iq.element("item");
	Double myLon = Double.parseDouble(item.attributeValue("lon"));
	Double myLat = Double.parseDouble(item.attributeValue("lat"));

	boolean f = insertLocation(myLon,myLat,username);
	if (f){
		// reply.setChildElement(iq);
	}else{
		reply.setType(IQ.Type.error);
		reply.setError(PacketError.Condition.internal_server_error);
	}
	
	return reply;
}
 
Example 7
Source File: IQPrivacyHandler.java    From Openfire with Apache License 2.0 6 votes vote down vote up
/**
 * User has specified that there is no default list that should be used for this user.
 *
 * @param packet IQ packet declining default list for all sessions.
 * @param from sender of the IQ packet.
 * @return acknowledge of success.
 */
private IQ declineDefaultList(IQ packet, JID from) {
    IQ result = IQ.createResultIQ(packet);
    Element childElement = packet.getChildElement().createCopy();
    result.setChildElement(childElement);

    if (sessionManager.getSessionCount(from.getNode()) > 1) {
        // Current default list is being used by more than one session
        result.setError(PacketError.Condition.conflict);
    }
    else {
        // Get the user session
        ClientSession session = sessionManager.getSession(from);
        // Check if a default list was already defined
        if (session.getDefaultList() != null) {
            // Set the existing default list as non-default
            session.getDefaultList().setDefaultList(false);
            // Update the database with the new list state
            provider.updatePrivacyList(from.getNode(), session.getDefaultList());
            session.setDefaultList(null);
        }
    }
    return result;
}
 
Example 8
Source File: LocalMUCRoom.java    From Openfire with Apache License 2.0 5 votes vote down vote up
@Override
public void send(@Nonnull Packet packet, @Nonnull MUCRole sender) {
    if (packet instanceof Message) {
        broadcast((Message)packet, sender);
    }
    else if (packet instanceof Presence) {
        broadcastPresence((Presence)packet, false, sender);
    }
    else if (packet instanceof IQ) {
        IQ reply = IQ.createResultIQ((IQ) packet);
        reply.setChildElement(((IQ) packet).getChildElement());
        reply.setError(PacketError.Condition.bad_request);
        router.route(reply);
    }
}
 
Example 9
Source File: IQPrivateHandler.java    From Openfire with Apache License 2.0 5 votes vote down vote up
@Override
public IQ handleIQ(IQ packet) throws UnauthorizedException, PacketException {
    IQ replyPacket = IQ.createResultIQ(packet);

    Element child = packet.getChildElement();
    Element dataElement = child.elementIterator().next();

    if ( !XMPPServer.getInstance().isLocal( packet.getFrom()) || !UserManager.getInstance().isRegisteredUser( packet.getFrom()) ) {
        replyPacket.setChildElement(packet.getChildElement().createCopy());
        replyPacket.setError(PacketError.Condition.service_unavailable);
        replyPacket.getError().setText( "Service available only to locally registered users." );
        return replyPacket;
    }

    if (dataElement != null) {
        if (IQ.Type.get.equals(packet.getType())) {
            Element dataStored = privateStorage.get(packet.getFrom().getNode(), dataElement);
            dataStored.setParent(null);

            child.remove(dataElement);
            child.setParent(null);
            replyPacket.setChildElement(child);
            child.add(dataStored);
        }
        else {
            if (privateStorage.isEnabled()) {
                privateStorage.add(packet.getFrom().getNode(), dataElement);
            } else {
                replyPacket.setChildElement(packet.getChildElement().createCopy());
                replyPacket.setError(PacketError.Condition.service_unavailable);
            }
        }
    }
    else {
        replyPacket.setChildElement("query", "jabber:iq:private");
    }
    return replyPacket;
}
 
Example 10
Source File: IQPEPHandler.java    From Openfire with Apache License 2.0 5 votes vote down vote up
@Override
public IQ handleIQ(IQ packet) {
    // Do nothing if server is not enabled
    if (!isEnabled()) {
        IQ reply = IQ.createResultIQ(packet);
        reply.setChildElement(packet.getChildElement().createCopy());
        reply.setError(PacketError.Condition.service_unavailable);
        return reply;
    }

    if (packet.getTo() == null || packet.getTo().equals( new JID(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) )
    {
        // packet addressed to service itself (not to a node/user)
        switch ( packet.getType() )
        {
            case set:
                return handleIQSetToService(packet );
            case get:
                return handleIQGetToService(packet );
            default:
                return null; // Ignore 'error' and 'result' stanzas.
        }
    }
    else
    {
        // packet was addressed to a node.
        if ( packet.isRequest() ) {
            return handleIQRequestToUser( packet );
        } else {
            return null; // Ignore IQ packets of type 'error' or 'result'.
        }
    }
}
 
Example 11
Source File: IQPrivacyHandler.java    From Openfire with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the IQ packet containing the details of the specified list. If no list
 * was found or the IQ request contains more than one specified list then an error will
 * be returned.
 *
 * @param packet IQ packet requesting a given list.
 * @param from sender of the IQ packet.
 * @return the IQ packet containing the details of the specified list.
 */
private IQ getPrivacyList(IQ packet, JID from) {
    IQ result = IQ.createResultIQ(packet);
    Element childElement = packet.getChildElement().createCopy();
    result.setChildElement(childElement);

    // Check that only one list was requested
    List<Element> lists = childElement.elements("list");
    if (lists.size() > 1) {
        result.setError(PacketError.Condition.bad_request);
    }
    else {
        String listName = lists.get(0).attributeValue("name");
        PrivacyList list = null;
        if (listName != null) {
            // A list name was specified so get it
            list = manager.getPrivacyList(from.getNode(), listName);
        }
        if (list != null) {
            // Add the privacy list to the result
            childElement = result.setChildElement("query", "jabber:iq:privacy");
            childElement.add(list.asElement());
        }
        else {
            // List not found
            result.setError(PacketError.Condition.item_not_found);
        }
    }
    return result;
}
 
Example 12
Source File: IQPrivacyHandler.java    From Openfire with Apache License 2.0 5 votes vote down vote up
/**
 * User has specified a new default list that should be used for all session.
 *
 * @param packet IQ packet setting new default list for all sessions.
 * @param from sender of the IQ packet.
 * @param listName name of the new default list for all sessions.
 * @return acknowledge of success.
 */
private IQ setDefaultList(IQ packet, JID from, String listName) {
    IQ result = IQ.createResultIQ(packet);
    Element childElement = packet.getChildElement().createCopy();
    result.setChildElement(childElement);

    if (sessionManager.getSessionCount(from.getNode()) > 1) {
        // Current default list is being used by more than one session
        result.setError(PacketError.Condition.conflict);
    }
    else {
        // Get the list
        PrivacyList list = manager.getPrivacyList(from.getNode(), listName);
        if (list != null) {
            // Get the user session
            ClientSession session = sessionManager.getSession(from);
            PrivacyList oldDefaultList = session.getDefaultList();
            manager.changeDefaultList(from.getNode(), list, oldDefaultList);
            // Set the new default list for this session (the only existing session)
            session.setDefaultList(list);
        }
        else {
            // List not found
            result.setError(PacketError.Condition.item_not_found);
        }
    }
    return result;
}
 
Example 13
Source File: IQPrivacyHandler.java    From Openfire with Apache License 2.0 5 votes vote down vote up
private IQ deleteList(IQ packet, JID from, String listName) {
    ClientSession currentSession;
    IQ result = IQ.createResultIQ(packet);
    Element childElement = packet.getChildElement().createCopy();
    result.setChildElement(childElement);
    // Get the list to delete
    PrivacyList list = manager.getPrivacyList(from.getNode(), listName);

    if (list == null) {
        // List to delete was not found
        result.setError(PacketError.Condition.item_not_found);
        return result;
    }
    else {
        currentSession = sessionManager.getSession(from);
        // Check if the list is being used by another session
        for (ClientSession session : sessionManager.getSessions(from.getNode())) {
            if (currentSession == session) {
                // Ignore the active session for this checking
                continue;
            }
            if (list.equals(session.getDefaultList()) || list.equals(session.getActiveList())) {
                // List to delete is being used by another session so return a conflict error
                result.setError(PacketError.Condition.conflict);
                return result;
            }
        }
    }
    // Remove the list from the active session (if it was being used)
    if (list.equals(currentSession.getDefaultList())) {
        currentSession.setDefaultList(null);
    }
    if (list.equals(currentSession.getActiveList())) {
        currentSession.setActiveList(null);
    }
    manager.deletePrivacyList(from.getNode(), listName);
    return result;
}
 
Example 14
Source File: FileTransferProxy.java    From Openfire with Apache License 2.0 5 votes vote down vote up
@Override
public void process(Packet packet) throws UnauthorizedException, PacketException {
    // Check if the packet is a disco request or a packet with namespace iq:register
    if (packet instanceof IQ) {
        if (handleIQ((IQ) packet)) {
            // Do nothing
        }
        else {
            IQ reply = IQ.createResultIQ((IQ) packet);
            reply.setChildElement(((IQ) packet).getChildElement().createCopy());
            reply.setError(PacketError.Condition.feature_not_implemented);
            router.route(reply);
        }
    }
}
 
Example 15
Source File: MultiplexerPacketHandler.java    From Openfire with Apache License 2.0 5 votes vote down vote up
/**
 * Sends an IQ error with the specified condition to the sender of the original
 * IQ packet.
 *
 * @param packet     the packet to be bounced.
 * @param extraError application specific error or null if none.
 * @param error the error.
 */
private void sendErrorPacket(IQ packet, PacketError.Condition error, Element extraError) {
    IQ reply = IQ.createResultIQ(packet);
    reply.setChildElement(packet.getChildElement().createCopy());
    reply.setError(error);
    if (extraError != null) {
        // Add specific application error if available
        reply.getError().getElement().add(extraError);
    }
    deliver(reply);
}
 
Example 16
Source File: LocationHandler.java    From openfireLBS with Apache License 2.0 4 votes vote down vote up
/**
 * 
 * 
 * @param packet
 * @return
 */
private IQ getUsersNearme(IQ packet) {

	IQ reply = IQ.createResultIQ(packet);
	
	JID from = packet.getFrom();
	
	Element iq = packet.getChildElement();
	Element item = iq.element("item");
	Double myLon = Double.parseDouble(item.attributeValue("lon"));
	Double myLat = Double.parseDouble(item.attributeValue("lat"));
	
	// XXX: update user location firstly 
	insertLocation(myLon,myLat,from.getNode());
	
	// find users near me 
	PreparedStatement pstmt = null;
	ResultSet rs = null;
	try {
		pstmt = openfireConn.prepareStatement(SQL_USERS_NEARME);
		pstmt.setDouble(1, myLon);
		pstmt.setDouble(2, myLon);
		pstmt.setDouble(3, myLat);
		pstmt.setDouble(4, myLat);
		rs = pstmt.executeQuery();
		String username = null;
		double nearLon = 0;
		double nearLat = 0;
		while (rs.next()) {  
			username = rs.getString("username");
			nearLon = rs.getDouble("lon");
			nearLat = rs.getDouble("lat");
			Element e = iq.addElement("item");
			e.addAttribute("user", username);
			e.addAttribute("lon", Double.toString(nearLon));
			e.addAttribute("lat", Double.toString(nearLat));
		}
		reply.setChildElement(iq);
	} catch (SQLException e1) {
		reply.setType(IQ.Type.error);
		reply.setError(PacketError.Condition.internal_server_error);
		e1.printStackTrace();
	}
	return reply;
}
 
Example 17
Source File: IQRosterHandler.java    From Openfire with Apache License 2.0 4 votes vote down vote up
/**
 * The packet is a typical 'set' or 'get' update targeted at the server.
 * Notice that the set could be a roster removal in which case we have to
 * generate a local roster removal update as well as a new roster removal
 * to send to the the roster item's owner.
 *
 * @param packet The packet that triggered this update
 * @return Either a response to the roster update or null if the packet is corrupt and the session was closed down
 */
private IQ manageRoster(org.xmpp.packet.Roster packet) throws UnauthorizedException,
        UserAlreadyExistsException, SharedGroupException {

    IQ returnPacket = null;
    JID sender = packet.getFrom();
    IQ.Type type = packet.getType();

    try {
        if ((sender.getNode() == null || !RosterManager.isRosterServiceEnabled() ||
                !userManager.isRegisteredUser(sender.getNode())) &&
                IQ.Type.get == type) {
            // If anonymous user asks for his roster or roster service is disabled then
            // return an empty roster
            IQ reply = IQ.createResultIQ(packet);
            reply.setChildElement("query", "jabber:iq:roster");
            return reply;
        }
        if (!localServer.isLocal(sender)) {
            // Sender belongs to a remote server so discard this IQ request
            Log.warn("Discarding IQ roster packet of remote user: " + packet);
            return null;
        }

        Roster cachedRoster = userManager.getUser(sender.getNode()).getRoster();
        if (IQ.Type.get == type) {

            if (RosterManager.isRosterVersioningEnabled()) {
                String clientVersion = packet.getChildElement().attributeValue("ver");
                String latestVersion = String.valueOf( cachedRoster.hashCode() );
                // Whether or not the roster has been modified since the version ID enumerated by the client, ...
                if (!latestVersion.equals(clientVersion)) {
                    // ... the server MUST either return the complete roster
                    // (including a 'ver' attribute that signals the latest version)
                    returnPacket = cachedRoster.getReset();
                    returnPacket.getChildElement().addAttribute("ver", latestVersion );
                } else {
                    // ... or return an empty IQ-result
                    returnPacket = new org.xmpp.packet.IQ();
                }
            } else {
                returnPacket = cachedRoster.getReset();
            }
            returnPacket.setType(IQ.Type.result);
            returnPacket.setTo(sender);
            returnPacket.setID(packet.getID());
            // Force delivery of the response because we need to trigger
            // a presence probe from all contacts
            deliverer.deliver(returnPacket);
            returnPacket = null;
        }
        else if (IQ.Type.set == type) {
            returnPacket = IQ.createResultIQ(packet);

            // RFC 6121 2.3.3.  Error Cases:
            // The server MUST return a <bad-request/> stanza error to the client if the roster set contains any of the following violations:
            // The <query/> element contains more than one <item/> child element.
            if (packet.getItems().size() > 1) {
                returnPacket.setError(new PacketError(PacketError.Condition.bad_request, PacketError.Type.modify, "Query contains more than one item"));
            } else {
                for (org.xmpp.packet.Roster.Item item : packet.getItems()) {
                    if (item.getSubscription() == org.xmpp.packet.Roster.Subscription.remove) {
                        if (removeItem(cachedRoster, packet.getFrom(), item) == null) {
                            // RFC 6121 2.5.3.  Error Cases: If the value of the 'jid' attribute specifies an item that is not in the roster, then the server MUST return an <item-not-found/> stanza error.
                            returnPacket.setError(PacketError.Condition.item_not_found);
                        }
                    } else {
                        PacketError error = checkGroups(item.getGroups());
                        if (error != null) {
                            returnPacket.setError(error);
                        } else {
                            if (cachedRoster.isRosterItem(item.getJID())) {
                                // existing item
                                RosterItem cachedItem = cachedRoster.getRosterItem(item.getJID());
                                cachedItem.setAsCopyOf(item);
                                cachedRoster.updateRosterItem(cachedItem);
                            } else {
                                // new item
                                cachedRoster.createRosterItem(item);
                            }
                        }
                    }
                }
            }
        }
    }
    catch (UserNotFoundException e) {
        throw new UnauthorizedException(e);
    }

    return returnPacket;

}
 
Example 18
Source File: IQOfflineMessagesHandler.java    From Openfire with Apache License 2.0 4 votes vote down vote up
@Override
public IQ handleIQ(IQ packet) throws UnauthorizedException {
    IQ reply = IQ.createResultIQ(packet);
    Element offlineRequest = packet.getChildElement();

    JID from = packet.getFrom();
    if (offlineRequest.element("purge") != null) {
        // User requested to delete all offline messages
        messageStore.deleteMessages(from.getNode());
    }
    else if (offlineRequest.element("fetch") != null) {
        // Mark that offline messages shouldn't be sent when the user becomes available
        stopOfflineFlooding(from);
        // User requested to receive all offline messages
        for (OfflineMessage offlineMessage : messageStore.getMessages(from.getNode(), false)) {
            sendOfflineMessage(from, offlineMessage);
        }
    }
    else {
        for (Iterator it = offlineRequest.elementIterator("item"); it.hasNext();) {
            Element item = (Element) it.next();
            Date creationDate = null;
            try {
                creationDate = xmppDateTime.parseString(item.attributeValue("node"));
            } catch (ParseException e) {
                Log.error("Error parsing date", e);
            }
            if ("view".equals(item.attributeValue("action"))) {
                // User requested to receive specific message
                OfflineMessage offlineMsg = messageStore.getMessage(from.getNode(), creationDate);
                if (offlineMsg != null) {
                    sendOfflineMessage(from, offlineMsg);
                }
            }
            else if ("remove".equals(item.attributeValue("action"))) {
                // User requested to delete specific message
                if (messageStore.getMessage(from.getNode(), creationDate) != null) {
                    messageStore.deleteMessage(from.getNode(), creationDate);
                } else {
                    // If the requester is authorized but the node does not exist, the server MUST return a <item-not-found/> error.
                    reply.setError(PacketError.Condition.item_not_found);
                }
            }
        }
    }
    return reply;
}
 
Example 19
Source File: Node.java    From Openfire with Apache License 2.0 4 votes vote down vote up
/**
 * 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<>();
        existing.add( subscriptionsByJID.get( subscription.getJID().toString() ) ); // potentially null
        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
        PubSubPersistenceProviderManager.getInstance().getProvider().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);
    }

    // If subscription is pending then send notification to node owners asking to approve
    // 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);
        }
    }
}
 
Example 20
Source File: MultiUserChatServiceImpl.java    From Openfire with Apache License 2.0 4 votes vote down vote up
@Override
public void processPacket(final Packet packet) {

    Log.trace( "Routing stanza: {}", packet.toXML() );
    if (!isServiceEnabled()) {
        Log.trace( "Service is disabled. Ignoring stanza." );
        return;
    }
    // The MUC service will receive all the packets whose domain matches the domain of the MUC
    // service. This means that, for instance, a disco request should be responded by the
    // service itself instead of relying on the server to handle the request.
    try {
        // Check if the packet is a disco request or a packet with namespace iq:register
        if (packet instanceof IQ) {
            if (process((IQ)packet)) {
                Log.trace( "Done processing IQ stanza." );
                return;
            }
        } else if (packet instanceof Message) {
            final Message msg = (Message) packet;
            if (msg.getType() == Message.Type.error) {
                // Bounced message, drop user.
                removeUser(packet.getFrom());
                Log.trace( "Done processing Message stanza." );
                return;
            }
        } else if (packet instanceof Presence) {
            final Presence pres = (Presence) packet;
            if (pres.getType() == Presence.Type.error) {
                // Bounced presence, drop user.
                removeUser(packet.getFrom());
                Log.trace( "Done processing Presence stanza." );
                return;
            }
        }

        if ( packet.getTo().getNode() == null )
        {
            Log.trace( "Stanza was addressed at the service itself, which by now should have been handled." );
            if ( packet instanceof IQ && ((IQ) packet).isRequest() )
            {
                final IQ reply = IQ.createResultIQ( (IQ) packet );
                reply.setChildElement( ((IQ) packet).getChildElement().createCopy() );
                reply.setError( PacketError.Condition.feature_not_implemented );
                router.route( reply );
            }
            Log.debug( "Ignoring stanza addressed at conference service: {}", packet.toXML() );
        }
        else
        {
            Log.trace( "The stanza is a normal packet that should possibly be sent to the room." );
            final JID recipient = packet.getTo();
            final String roomName = recipient != null ? recipient.getNode() : null;
            final JID userJid = packet.getFrom();
            Log.trace( "Stanza recipient: {}, room name: {}, sender: {}", recipient, roomName, userJid );
            try (final AutoCloseableReentrantLock.AutoCloseableLock ignored = new AutoCloseableReentrantLock(MultiUserChatServiceImpl.class, userJid.toString()).lock()) {
                if ( !packet.getElement().elements(FMUCHandler.FMUC).isEmpty() ) {
                    Log.trace( "Stanza is a FMUC stanza." );
                    final MUCRoom chatRoom = getChatRoom(roomName);
                    if ( chatRoom != null ) {
                        chatRoom.getFmucHandler().process(packet);
                    } else {
                        Log.warn( "Unable to process FMUC stanza, as room it's addressed to does not exist: {}", roomName );
                        // FIXME need to send error back in case of IQ request, and FMUC join. Might want to send error back in other cases too.
                    }
                } else {
                    Log.trace( "Stanza is a regular MUC stanza." );
                    getChatUser(userJid, roomName).process(packet);
                }
            }
        }
    }
    catch (final Exception e) {
        Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
    }
}