Search in sources :

Example 11 with MUCRoom

use of org.jivesoftware.openfire.muc.MUCRoom in project Openfire by igniterealtime.

the class CreateMUCRoom method execute.

@Override
public void execute(SessionData sessionData, Element command) {
    Element note = command.addElement("note");
    Collection<JID> admins = XMPPServer.getInstance().getAdmins();
    if (admins.size() <= 0) {
        note.addAttribute("type", "error");
        note.setText("Server needs admin user to be able to create rooms.");
        return;
    }
    Map<String, List<String>> data = sessionData.getData();
    // Let's find the requested MUC service to create the room in
    String servicehostname = get(data, "servicename", 0);
    if (servicehostname == null) {
        note.addAttribute("type", "error");
        note.setText("Service name must be specified.");
        return;
    }
    // Remove the server's domain name from the passed hostname
    String servicename = servicehostname.replace("." + XMPPServer.getInstance().getServerInfo().getXMPPDomain(), "");
    MultiUserChatService mucService;
    mucService = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(servicename);
    if (mucService == null) {
        note.addAttribute("type", "error");
        note.setText("Invalid service name specified.");
        return;
    }
    if (!mucService.isServiceEnabled()) {
        note.addAttribute("type", "error");
        note.setText("Multi user chat is disabled for specified service.");
        return;
    }
    // Let's create the jid and check that they are a local user
    String roomname = get(data, "roomname", 0);
    if (roomname == null) {
        note.addAttribute("type", "error");
        note.setText("Room name must be specified.");
        return;
    }
    JID admin = admins.iterator().next();
    MUCRoom room;
    try {
        room = mucService.getChatRoom(roomname, admin);
    } catch (NotAllowedException e) {
        note.addAttribute("type", "error");
        note.setText("No permission to create rooms.");
        return;
    }
    boolean isPersistent = "1".equals(get(data, "persistent", 0));
    room.setPersistent(isPersistent);
    boolean isPublic = "1".equals(get(data, "public", 0));
    room.setPublicRoom(isPublic);
    String password = get(data, "password", 0);
    if (password != null) {
        room.setPassword(password);
    }
}
Also used : JID(org.xmpp.packet.JID) MUCRoom(org.jivesoftware.openfire.muc.MUCRoom) NotAllowedException(org.jivesoftware.openfire.muc.NotAllowedException) Element(org.dom4j.Element) MultiUserChatService(org.jivesoftware.openfire.muc.MultiUserChatService) List(java.util.List)

Example 12 with MUCRoom

use of org.jivesoftware.openfire.muc.MUCRoom in project Openfire by igniterealtime.

the class IQMUCRegisterHandler method handleIQ.

public IQ handleIQ(IQ packet) {
    IQ reply = null;
    // Get the target room
    MUCRoom room = null;
    String name = packet.getTo().getNode();
    if (name != null) {
        room = mucService.getChatRoom(name);
    }
    if (room == null) {
        // The room doesn't exist so answer a NOT_FOUND error
        reply = IQ.createResultIQ(packet);
        reply.setChildElement(packet.getChildElement().createCopy());
        reply.setError(PacketError.Condition.item_not_found);
        return reply;
    } else if (!room.isRegistrationEnabled() || (packet.getFrom() != null && MUCRole.Affiliation.outcast == room.getAffiliation(packet.getFrom().asBareJID()))) {
        // The room does not accept users to register or
        // the user is an outcast and is not allowed to register
        reply = IQ.createResultIQ(packet);
        reply.setChildElement(packet.getChildElement().createCopy());
        reply.setError(PacketError.Condition.not_allowed);
        return reply;
    }
    if (IQ.Type.get == packet.getType()) {
        reply = IQ.createResultIQ(packet);
        String nickname = room.getReservedNickname(packet.getFrom());
        Element currentRegistration = probeResult.createCopy();
        if (nickname != null) {
            // The user is already registered with the room so answer a completed form
            ElementUtil.setProperty(currentRegistration, "query.registered", null);
            currentRegistration.addElement("username").addText(nickname);
            Element form = currentRegistration.element(QName.get("x", "jabber:x:data"));
            currentRegistration.remove(form);
            //                @SuppressWarnings("unchecked")
            //				Iterator<Element> fields = form.elementIterator("field");
            //
            //                Element field;
            //                while (fields.hasNext()) {
            //                    field = fields.next();
            //                    if ("muc#register_roomnick".equals(field.attributeValue("var"))) {
            //                        field.addElement("value").addText(nickname);
            //                    }
            //                }
            reply.setChildElement(currentRegistration);
        } else {
            // The user is not registered with the room so answer an empty form
            reply.setChildElement(currentRegistration);
        }
    } else if (IQ.Type.set == packet.getType()) {
        try {
            // Keep a registry of the updated presences
            List<Presence> presences = new ArrayList<>();
            reply = IQ.createResultIQ(packet);
            Element iq = packet.getChildElement();
            if (ElementUtil.includesProperty(iq, "query.remove")) {
                // The user is deleting his registration
                presences.addAll(room.addNone(packet.getFrom(), room.getRole()));
            } else {
                // The user is trying to register with a room
                Element formElement = iq.element("x");
                // Check if a form was used to provide the registration info
                if (formElement != null) {
                    // Get the sent form
                    final DataForm registrationForm = new DataForm(formElement);
                    // Get the desired nickname sent in the form
                    List<String> values = registrationForm.getField("muc#register_roomnick").getValues();
                    String nickname = (!values.isEmpty() ? values.get(0) : null);
                    // TODO The rest of the fields of the form are ignored. If we have a
                    // requirement in the future where we need those fields we'll have to change
                    // MUCRoom.addMember in order to receive a RegistrationInfo (new class)
                    // Add the new member to the members list
                    presences.addAll(room.addMember(packet.getFrom(), nickname, room.getRole()));
                } else {
                    reply.setChildElement(packet.getChildElement().createCopy());
                    reply.setError(PacketError.Condition.bad_request);
                }
            }
            // Send the updated presences to the room occupants
            for (Presence presence : presences) {
                room.send(presence);
            }
        } catch (ForbiddenException e) {
            reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(PacketError.Condition.forbidden);
        } catch (ConflictException e) {
            reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(PacketError.Condition.conflict);
        } catch (Exception e) {
            Log.error(e.getMessage(), e);
        }
    }
    return reply;
}
Also used : ForbiddenException(org.jivesoftware.openfire.muc.ForbiddenException) MUCRoom(org.jivesoftware.openfire.muc.MUCRoom) ConflictException(org.jivesoftware.openfire.muc.ConflictException) Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ) DataForm(org.xmpp.forms.DataForm) Presence(org.xmpp.packet.Presence) ArrayList(java.util.ArrayList) List(java.util.List) ForbiddenException(org.jivesoftware.openfire.muc.ForbiddenException) ConflictException(org.jivesoftware.openfire.muc.ConflictException)

Example 13 with MUCRoom

use of org.jivesoftware.openfire.muc.MUCRoom in project Openfire by igniterealtime.

the class IQMUCSearchHandler method handleIQ.

/**
	 * Constructs an answer on a IQ stanza that contains a search request. The
	 * answer will be an IQ stanza of type 'result' or 'error'.
	 * 
	 * @param iq
	 *            The IQ stanza that is the search request.
	 * @return An answer to the provided request.
	 */
public IQ handleIQ(IQ iq) {
    final IQ reply = IQ.createResultIQ(iq);
    final Element formElement = iq.getChildElement().element(QName.get("x", "jabber:x:data"));
    if (formElement == null) {
        reply.setChildElement(getDataElement());
        return reply;
    }
    // parse params from request.
    final DataForm df = new DataForm(formElement);
    boolean name_is_exact_match = false;
    String subject = null;
    int numusers = -1;
    int numaxusers = -1;
    boolean includePasswordProtectedRooms = true;
    final Set<String> names = new HashSet<>();
    for (final FormField field : df.getFields()) {
        if (field.getVariable().equals("name")) {
            names.add(field.getFirstValue());
        }
    }
    final FormField matchFF = df.getField("name_is_exact_match");
    if (matchFF != null) {
        final String b = matchFF.getFirstValue();
        if (b != null) {
            name_is_exact_match = b.equals("1") || b.equalsIgnoreCase("true") || b.equalsIgnoreCase("yes");
        }
    }
    final FormField subjectFF = df.getField("subject");
    if (subjectFF != null) {
        subject = subjectFF.getFirstValue();
    }
    try {
        final FormField userAmountFF = df.getField("num_users");
        if (userAmountFF != null) {
            String value = userAmountFF.getFirstValue();
            if (value != null && !"".equals(value)) {
                numusers = Integer.parseInt(value);
            }
        }
        final FormField maxUsersFF = df.getField("num_max_users");
        if (maxUsersFF != null) {
            String value = maxUsersFF.getFirstValue();
            if (value != null && !"".equals(value)) {
                numaxusers = Integer.parseInt(value);
            }
        }
    } catch (NumberFormatException e) {
        reply.setError(PacketError.Condition.bad_request);
        return reply;
    }
    final FormField includePasswordProtectedRoomsFF = df.getField("include_password_protected");
    if (includePasswordProtectedRoomsFF != null) {
        final String b = includePasswordProtectedRoomsFF.getFirstValue();
        if (b != null) {
            if (b.equals("0") || b.equalsIgnoreCase("false") || b.equalsIgnoreCase("no")) {
                includePasswordProtectedRooms = false;
            }
        }
    }
    // search for chatrooms matching the request params.
    final List<MUCRoom> mucs = new ArrayList<>();
    for (MUCRoom room : mucService.getChatRooms()) {
        boolean find = false;
        if (names.size() > 0) {
            for (final String name : names) {
                if (name_is_exact_match) {
                    if (name.equalsIgnoreCase(room.getNaturalLanguageName())) {
                        find = true;
                        break;
                    }
                } else {
                    if (room.getNaturalLanguageName().toLowerCase().indexOf(name.toLowerCase()) != -1) {
                        find = true;
                        break;
                    }
                }
            }
        }
        if (subject != null && room.getSubject().toLowerCase().indexOf(subject.toLowerCase()) != -1) {
            find = true;
        }
        if (numusers > -1 && room.getParticipants().size() < numusers) {
            find = false;
        }
        if (numaxusers > -1 && room.getMaxUsers() < numaxusers) {
            find = false;
        }
        if (!includePasswordProtectedRooms && room.isPasswordProtected()) {
            find = false;
        }
        if (find && canBeIncludedInResult(room)) {
            mucs.add(room);
        }
    }
    final ResultSet<MUCRoom> searchResults = new ResultSetImpl<>(sortByUserAmount(mucs));
    // See if the requesting entity would like to apply 'result set
    // management'
    final Element set = iq.getChildElement().element(QName.get("set", ResultSet.NAMESPACE_RESULT_SET_MANAGEMENT));
    final List<MUCRoom> mucrsm;
    // apply RSM only if the element exists, and the (total) results
    // set is not empty.
    final boolean applyRSM = set != null && !mucs.isEmpty();
    if (applyRSM) {
        if (!ResultSet.isValidRSMRequest(set)) {
            reply.setError(Condition.bad_request);
            return reply;
        }
        try {
            mucrsm = searchResults.applyRSMDirectives(set);
        } catch (NullPointerException e) {
            final IQ itemNotFound = IQ.createResultIQ(iq);
            itemNotFound.setError(Condition.item_not_found);
            return itemNotFound;
        }
    } else {
        // if no rsm, all found rooms are part of the result.
        mucrsm = new ArrayList<>(searchResults);
    }
    final Element res = DocumentHelper.createElement(QName.get("query", "jabber:iq:search"));
    final DataForm resultform = new DataForm(DataForm.Type.result);
    boolean atLeastoneResult = false;
    for (MUCRoom room : mucrsm) {
        final Map<String, Object> fields = new HashMap<>();
        fields.put("name", room.getNaturalLanguageName());
        fields.put("subject", room.getSubject());
        fields.put("num_users", room.getOccupantsCount());
        fields.put("num_max_users", room.getMaxUsers());
        fields.put("is_password_protected", room.isPasswordProtected());
        fields.put("is_member_only", room.isMembersOnly());
        fields.put("jid", room.getRole().getRoleAddress().toString());
        resultform.addItemFields(fields);
        atLeastoneResult = true;
    }
    if (atLeastoneResult) {
        resultform.addReportedField("name", "Name", FormField.Type.text_single);
        resultform.addReportedField("subject", "Subject", FormField.Type.text_single);
        resultform.addReportedField("num_users", "Number of users", FormField.Type.text_single);
        resultform.addReportedField("num_max_users", "Max number allowed of users", FormField.Type.text_single);
        resultform.addReportedField("is_password_protected", "Is a password protected room.", FormField.Type.boolean_type);
        resultform.addReportedField("is_member_only", "Is a member only room.", FormField.Type.boolean_type);
        resultform.addReportedField("jid", "JID", FormField.Type.jid_single);
    }
    res.add(resultform.getElement());
    if (applyRSM) {
        res.add(searchResults.generateSetElementFromResults(mucrsm));
    }
    reply.setChildElement(res);
    return reply;
}
Also used : ResultSetImpl(org.xmpp.resultsetmanagement.ResultSetImpl) Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ) MUCRoom(org.jivesoftware.openfire.muc.MUCRoom) DataForm(org.xmpp.forms.DataForm) FormField(org.xmpp.forms.FormField)

Example 14 with MUCRoom

use of org.jivesoftware.openfire.muc.MUCRoom in project Openfire by igniterealtime.

the class MultiUserChatServiceImpl method broadcastShutdown.

/**
     * Informs all users local to this cluster node that he or she is being removed from the room because the MUC
     * service is being shut down.
     *
     * The implementation is optimized to run as fast as possible (to prevent prolonging the shutdown).
     */
private void broadcastShutdown() {
    Log.debug("Notifying all local users about the imminent destruction of chat service '{}'", chatServiceName);
    if (users.isEmpty()) {
        return;
    }
    // A thread pool is used to broadcast concurrently, as well as to limit the execution time of this service.
    final ExecutorService service = Executors.newFixedThreadPool(Math.min(users.size(), 10));
    // Queue all tasks in the executor service.
    for (final LocalMUCUser user : users.values()) {
        // Submit a concurrent task for each local user (that could be in more than one (local) room).
        service.submit(new Runnable() {

            @Override
            public void run() {
                try {
                    for (final LocalMUCRole role : user.getRoles()) {
                        final MUCRoom room = role.getChatRoom();
                        // Send a presence stanza of type "unavailable" to the occupant
                        final Presence presence = room.createPresence(Presence.Type.unavailable);
                        presence.setFrom(role.getRoleAddress());
                        // A fragment containing the x-extension.
                        final Element fragment = presence.addChildElement("x", "http://jabber.org/protocol/muc#user");
                        final Element item = fragment.addElement("item");
                        item.addAttribute("affiliation", "none");
                        item.addAttribute("role", "none");
                        fragment.addElement("status").addAttribute("code", "332");
                        // Make sure that the presence change for each user is only sent to that user (and not broadcasted in the room)!
                        role.send(presence);
                    }
                } catch (Exception e) {
                    Log.debug("Unable to inform {} about the imminent destruction of chat service '{}'", user.getAddress(), chatServiceName, e);
                }
            }
        });
    }
    // Try to shutdown - wait - force shutdown.
    service.shutdown();
    try {
        service.awaitTermination(JiveGlobals.getIntProperty("xmpp.muc.await-termination-millis", 500), TimeUnit.MILLISECONDS);
        Log.debug("Successfully notified all {} local users about the imminent destruction of chat service '{}'", users.size(), chatServiceName);
    } catch (InterruptedException e) {
        Log.debug("Interrupted while waiting for all users to be notified of shutdown of chat service '{}'. Shutting down immediately.", chatServiceName);
    }
    service.shutdownNow();
}
Also used : MUCRoom(org.jivesoftware.openfire.muc.MUCRoom) Element(org.dom4j.Element) ExecutorService(java.util.concurrent.ExecutorService) NotAllowedException(org.jivesoftware.openfire.muc.NotAllowedException) UnauthorizedException(org.jivesoftware.openfire.auth.UnauthorizedException)

Example 15 with MUCRoom

use of org.jivesoftware.openfire.muc.MUCRoom in project Openfire by igniterealtime.

the class MultiUserChatServiceImpl method checkForTimedOutUsers.

private void checkForTimedOutUsers() {
    final long deadline = System.currentTimeMillis() - user_idle;
    for (LocalMUCUser user : users.values()) {
        try {
            // the list of users
            if (!user.isJoined()) {
                removeUser(user.getAddress());
                continue;
            }
            // Do nothing if this feature is disabled (i.e USER_IDLE equals -1)
            if (user_idle == -1) {
                continue;
            }
            if (user.getLastPacketTime() < deadline) {
                // Kick the user from all the rooms that he/she had previuosly joined
                MUCRoom room;
                Presence kickedPresence;
                for (LocalMUCRole role : user.getRoles()) {
                    room = role.getChatRoom();
                    try {
                        kickedPresence = room.kickOccupant(user.getAddress(), null, null, null);
                        // Send the updated presence to the room occupants
                        room.send(kickedPresence);
                    } catch (NotAllowedException e) {
                    // Do nothing since we cannot kick owners or admins
                    }
                }
            }
        } catch (Throwable e) {
            Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
        }
    }
}
Also used : MUCRoom(org.jivesoftware.openfire.muc.MUCRoom) NotAllowedException(org.jivesoftware.openfire.muc.NotAllowedException)

Aggregations

MUCRoom (org.jivesoftware.openfire.muc.MUCRoom)20 ArrayList (java.util.ArrayList)6 Date (java.util.Date)5 Element (org.dom4j.Element)5 LocalMUCRoom (org.jivesoftware.openfire.muc.spi.LocalMUCRoom)5 JID (org.xmpp.packet.JID)5 MultiUserChatService (org.jivesoftware.openfire.muc.MultiUserChatService)4 NotAllowedException (org.jivesoftware.openfire.muc.NotAllowedException)3 DataForm (org.xmpp.forms.DataForm)3 ArchivedMessage (com.reucon.openfire.plugin.archive.model.ArchivedMessage)2 List (java.util.List)2 MUCRoomEntity (org.jivesoftware.openfire.entity.MUCRoomEntity)2 ConflictException (org.jivesoftware.openfire.muc.ConflictException)2 ForbiddenException (org.jivesoftware.openfire.muc.ForbiddenException)2 MUCRole (org.jivesoftware.openfire.muc.MUCRole)2 MUCRoomEntity (org.jivesoftware.openfire.plugin.rest.entity.MUCRoomEntity)2 ServiceException (org.jivesoftware.openfire.plugin.rest.exceptions.ServiceException)2 FormField (org.xmpp.forms.FormField)2 IQ (org.xmpp.packet.IQ)2 Presence (org.xmpp.packet.Presence)2