Search in sources :

Example 46 with DataForm

use of org.xmpp.forms.DataForm in project Openfire by igniterealtime.

the class SearchPlugin method processGetPacket.

/**
	 * Processes an IQ stanza of type 'get', which in the context of 'Jabber Search' is a request for available search fields.
	 * 
	 * @param packet
	 *            An IQ stanza of type 'get'
	 * @return A result IQ stanza that contains the possbile search fields.
	 */
private IQ processGetPacket(IQ packet) {
    if (!packet.getType().equals(IQ.Type.get)) {
        throw new IllegalArgumentException("This method only accepts 'get' typed IQ stanzas as an argument.");
    }
    IQ replyPacket = IQ.createResultIQ(packet);
    Element queryResult = DocumentHelper.createElement(QName.get("query", NAMESPACE_JABBER_IQ_SEARCH));
    String instructions = LocaleUtils.getLocalizedString("advance.user.search.details", "search");
    // non-data form
    queryResult.addElement("instructions").addText(instructions);
    queryResult.addElement("first");
    queryResult.addElement("last");
    queryResult.addElement("nick");
    queryResult.addElement("email");
    DataForm searchForm = new DataForm(DataForm.Type.form);
    searchForm.setTitle(LocaleUtils.getLocalizedString("advance.user.search.title", "search"));
    searchForm.addInstruction(instructions);
    searchForm.addField("FORM_TYPE", null, FormField.Type.hidden).addValue(NAMESPACE_JABBER_IQ_SEARCH);
    searchForm.addField("search", LocaleUtils.getLocalizedString("advance.user.search.search", "search"), FormField.Type.text_single).setRequired(true);
    for (String searchField : getFilteredSearchFields()) {
        final FormField field = searchForm.addField();
        field.setVariable(searchField);
        field.setType(FormField.Type.boolean_type);
        field.addValue("1");
        field.setLabel(LocaleUtils.getLocalizedString("advance.user.search." + searchField.toLowerCase(), "search"));
        field.setRequired(false);
    }
    queryResult.add(searchForm.getElement());
    replyPacket.setChildElement(queryResult);
    return replyPacket;
}
Also used : Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ) DataForm(org.xmpp.forms.DataForm) FormField(org.xmpp.forms.FormField)

Example 47 with DataForm

use of org.xmpp.forms.DataForm in project Openfire by igniterealtime.

the class SearchPlugin method replyDataFormResult.

/**
	 * Constructs a query that is returned as an IQ packet that contains the search results.
	 * 
	 * @param users
	 *            set of users that will be used to construct the search results
	 * @param packet
	 *            the IQ packet sent by the client
	 * @return the iq packet that contains the search results
	 */
private IQ replyDataFormResult(Collection<User> users, IQ packet) {
    final DataForm searchResults = new DataForm(DataForm.Type.result);
    searchResults.addField("FORM_TYPE", null, FormField.Type.hidden);
    searchResults.addReportedField("jid", "JID", FormField.Type.jid_single);
    for (final String fieldName : getFilteredSearchFields()) {
        searchResults.addReportedField(fieldName, LocaleUtils.getLocalizedString("advance.user.search." + fieldName.toLowerCase(), "search"), FormField.Type.text_single);
    }
    for (final User user : users) {
        final String username = JID.unescapeNode(user.getUsername());
        final Map<String, Object> item = new HashMap<String, Object>();
        item.put("jid", username + "@" + serverName);
        item.put(LocaleUtils.getLocalizedString("advance.user.search.username", "search"), username);
        item.put(LocaleUtils.getLocalizedString("advance.user.search.name", "search"), (user.isNameVisible() ? removeNull(user.getName()) : ""));
        item.put(LocaleUtils.getLocalizedString("advance.user.search.email", "search"), (user.isEmailVisible() ? removeNull(user.getEmail()) : ""));
        searchResults.addItemFields(item);
    }
    IQ replyPacket = IQ.createResultIQ(packet);
    Element reply = replyPacket.setChildElement("query", NAMESPACE_JABBER_IQ_SEARCH);
    reply.add(searchResults.getElement());
    return replyPacket;
}
Also used : User(org.jivesoftware.openfire.user.User) HashMap(java.util.HashMap) Element(org.dom4j.Element) DataForm(org.xmpp.forms.DataForm) IQ(org.xmpp.packet.IQ)

Example 48 with DataForm

use of org.xmpp.forms.DataForm in project Openfire by igniterealtime.

the class IQRegisterHandler method handleIQ.

@Override
public IQ handleIQ(IQ packet) throws PacketException, UnauthorizedException {
    ClientSession session = sessionManager.getSession(packet.getFrom());
    IQ reply = null;
    // If no session was found then answer an error (if possible)
    if (session == null) {
        Log.error("Error during registration. Session not found in " + sessionManager.getPreAuthenticatedKeys() + " for key " + packet.getFrom());
        // This error packet will probably won't make it through
        reply = IQ.createResultIQ(packet);
        reply.setChildElement(packet.getChildElement().createCopy());
        reply.setError(PacketError.Condition.internal_server_error);
        return reply;
    }
    if (IQ.Type.get.equals(packet.getType())) {
        // If inband registration is not allowed, return an error.
        if (!registrationEnabled) {
            reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(PacketError.Condition.forbidden);
        } else {
            reply = IQ.createResultIQ(packet);
            if (session.getStatus() == Session.STATUS_AUTHENTICATED) {
                try {
                    User user = userManager.getUser(session.getUsername());
                    Element currentRegistration = probeResult.createCopy();
                    currentRegistration.addElement("registered");
                    currentRegistration.element("username").setText(user.getUsername());
                    currentRegistration.element("password").setText("");
                    currentRegistration.element("email").setText(user.getEmail() == null ? "" : user.getEmail());
                    currentRegistration.element("name").setText(user.getName());
                    Element form = currentRegistration.element(QName.get("x", "jabber:x:data"));
                    Iterator fields = form.elementIterator("field");
                    Element field;
                    while (fields.hasNext()) {
                        field = (Element) fields.next();
                        if ("username".equals(field.attributeValue("var"))) {
                            field.addElement("value").addText(user.getUsername());
                        } else if ("name".equals(field.attributeValue("var"))) {
                            field.addElement("value").addText(user.getName());
                        } else if ("email".equals(field.attributeValue("var"))) {
                            field.addElement("value").addText(user.getEmail() == null ? "" : user.getEmail());
                        }
                    }
                    reply.setChildElement(currentRegistration);
                } catch (UserNotFoundException e) {
                    reply.setChildElement(probeResult.createCopy());
                }
            } else {
                // This is a workaround. Since we don't want to have an incorrect TO attribute
                // value we need to clean up the TO attribute. The TO attribute will contain an
                // incorrect value since we are setting a fake JID until the user actually
                // authenticates with the server.
                reply.setTo((JID) null);
                reply.setChildElement(probeResult.createCopy());
            }
        }
    } else if (IQ.Type.set.equals(packet.getType())) {
        try {
            Element iqElement = packet.getChildElement();
            if (iqElement.element("remove") != null) {
                // If inband registration is not allowed, return an error.
                if (!registrationEnabled) {
                    reply = IQ.createResultIQ(packet);
                    reply.setChildElement(packet.getChildElement().createCopy());
                    reply.setError(PacketError.Condition.forbidden);
                } else {
                    if (session.getStatus() == Session.STATUS_AUTHENTICATED) {
                        User user = userManager.getUser(session.getUsername());
                        // Delete the user
                        userManager.deleteUser(user);
                        // Delete the roster of the user
                        rosterManager.deleteRoster(session.getAddress());
                        // Delete the user from all the Groups
                        GroupManager.getInstance().deleteUser(user);
                        reply = IQ.createResultIQ(packet);
                        session.process(reply);
                        // Take a quick nap so that the client can process the result
                        Thread.sleep(10);
                        // Close the user's connection
                        final StreamError error = new StreamError(StreamError.Condition.not_authorized);
                        for (ClientSession sess : sessionManager.getSessions(user.getUsername())) {
                            sess.deliverRawText(error.toXML());
                            sess.close();
                        }
                        // The reply has been sent so clean up the variable
                        reply = null;
                    } else {
                        throw new UnauthorizedException();
                    }
                }
            } else {
                String username;
                String password = null;
                String email = null;
                String name = null;
                User newUser;
                DataForm registrationForm;
                FormField field;
                Element formElement = iqElement.element("x");
                // Check if a form was used to provide the registration info
                if (formElement != null) {
                    // Get the sent form
                    registrationForm = new DataForm(formElement);
                    // Get the username sent in the form
                    List<String> values = registrationForm.getField("username").getValues();
                    username = (!values.isEmpty() ? values.get(0) : " ");
                    // Get the password sent in the form
                    field = registrationForm.getField("password");
                    if (field != null) {
                        values = field.getValues();
                        password = (!values.isEmpty() ? values.get(0) : " ");
                    }
                    // Get the email sent in the form
                    field = registrationForm.getField("email");
                    if (field != null) {
                        values = field.getValues();
                        email = (!values.isEmpty() ? values.get(0) : " ");
                    }
                    // Get the name sent in the form
                    field = registrationForm.getField("name");
                    if (field != null) {
                        values = field.getValues();
                        name = (!values.isEmpty() ? values.get(0) : " ");
                    }
                } else {
                    // Get the registration info from the query elements
                    username = iqElement.elementText("username");
                    password = iqElement.elementText("password");
                    email = iqElement.elementText("email");
                    name = iqElement.elementText("name");
                }
                if (email != null && email.matches("\\s*")) {
                    email = null;
                }
                if (name != null && name.matches("\\s*")) {
                    name = null;
                }
                // stringprep validity now.
                if (username != null) {
                    Stringprep.nodeprep(username);
                }
                if (session.getStatus() == Session.STATUS_AUTHENTICATED) {
                    // Flag that indicates if the user is *only* changing his password
                    boolean onlyPassword = false;
                    if (iqElement.elements().size() == 2 && iqElement.element("username") != null && iqElement.element("password") != null) {
                        onlyPassword = true;
                    }
                    // If users are not allowed to change their password, return an error.
                    if (password != null && !canChangePassword) {
                        reply = IQ.createResultIQ(packet);
                        reply.setChildElement(packet.getChildElement().createCopy());
                        reply.setError(PacketError.Condition.forbidden);
                        return reply;
                    } else // If inband registration is not allowed, return an error.
                    if (!onlyPassword && !registrationEnabled) {
                        reply = IQ.createResultIQ(packet);
                        reply.setChildElement(packet.getChildElement().createCopy());
                        reply.setError(PacketError.Condition.forbidden);
                        return reply;
                    } else {
                        User user = userManager.getUser(session.getUsername());
                        if (user.getUsername().equalsIgnoreCase(username)) {
                            if (password != null && password.trim().length() > 0) {
                                user.setPassword(password);
                            }
                            if (!onlyPassword) {
                                user.setEmail(email);
                            }
                            newUser = user;
                        } else if (password != null && password.trim().length() > 0) {
                            // An admin can create new accounts when logged in.
                            newUser = userManager.createUser(username, password, null, email);
                        } else {
                            // Deny registration of users with no password
                            reply = IQ.createResultIQ(packet);
                            reply.setChildElement(packet.getChildElement().createCopy());
                            reply.setError(PacketError.Condition.not_acceptable);
                            return reply;
                        }
                    }
                } else {
                    // If inband registration is not allowed, return an error.
                    if (!registrationEnabled) {
                        reply = IQ.createResultIQ(packet);
                        reply.setChildElement(packet.getChildElement().createCopy());
                        reply.setError(PacketError.Condition.forbidden);
                        return reply;
                    } else // information was not provided
                    if (password == null || password.trim().length() == 0) {
                        reply = IQ.createResultIQ(packet);
                        reply.setChildElement(packet.getChildElement().createCopy());
                        reply.setError(PacketError.Condition.not_acceptable);
                        return reply;
                    } else {
                        // Create the new account
                        newUser = userManager.createUser(username, password, name, email);
                    }
                }
                // Set and save the extra user info (e.g. full name, etc.)
                if (newUser != null && name != null && !name.equals(newUser.getName())) {
                    newUser.setName(name);
                }
                reply = IQ.createResultIQ(packet);
            }
        } catch (UserAlreadyExistsException e) {
            reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(PacketError.Condition.conflict);
        } catch (UserNotFoundException e) {
            reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(PacketError.Condition.bad_request);
        } catch (StringprepException e) {
            // The specified username is not correct according to the stringprep specs
            reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(PacketError.Condition.jid_malformed);
        } catch (IllegalArgumentException e) {
            // At least one of the fields passed in is not valid
            reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(PacketError.Condition.not_acceptable);
            Log.warn(e.getMessage(), e);
        } catch (UnsupportedOperationException e) {
            // The User provider is read-only so this operation is not allowed
            reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(PacketError.Condition.not_allowed);
        } catch (Exception e) {
            // Some unexpected error happened so return an internal_server_error
            reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(PacketError.Condition.internal_server_error);
            Log.error(e.getMessage(), e);
        }
    }
    if (reply != null) {
        // why is this done here instead of letting the iq handler do it?
        session.process(reply);
    }
    return null;
}
Also used : UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) User(org.jivesoftware.openfire.user.User) Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ) UserAlreadyExistsException(org.jivesoftware.openfire.user.UserAlreadyExistsException) StringprepException(gnu.inet.encoding.StringprepException) PacketException(org.jivesoftware.openfire.PacketException) UnauthorizedException(org.jivesoftware.openfire.auth.UnauthorizedException) UserAlreadyExistsException(org.jivesoftware.openfire.user.UserAlreadyExistsException) UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) StringprepException(gnu.inet.encoding.StringprepException) StreamError(org.xmpp.packet.StreamError) ClientSession(org.jivesoftware.openfire.session.ClientSession) Iterator(java.util.Iterator) UnauthorizedException(org.jivesoftware.openfire.auth.UnauthorizedException) DataForm(org.xmpp.forms.DataForm) List(java.util.List) FormField(org.xmpp.forms.FormField)

Example 49 with DataForm

use of org.xmpp.forms.DataForm in project Openfire by igniterealtime.

the class PubSubEngine method configureNode.

private void configureNode(PubSubService service, IQ iq, Element configureElement, String nodeID) {
    Node node = service.getNode(nodeID);
    if (node == null) {
        // Node does not exist. Return item-not-found error
        sendErrorPacket(iq, PacketError.Condition.item_not_found, null);
        return;
    }
    if (!node.isAdmin(iq.getFrom())) {
        // Requesting entity is not allowed to get node configuration. Return forbidden error
        sendErrorPacket(iq, PacketError.Condition.forbidden, null);
        return;
    }
    // Get the data form that contains the parent nodeID
    DataForm completedForm = getSentConfigurationForm(configureElement);
    if (completedForm != null) {
        try {
            // Update node configuration with the provided data form
            // (and update the backend store)
            node.configure(completedForm);
            CacheFactory.doClusterTask(new RefreshNodeTask(node));
            // Return that node configuration was successful
            router.route(IQ.createResultIQ(iq));
        } catch (NotAcceptableException e) {
            // Node should have at least one owner. Return not-acceptable error.
            sendErrorPacket(iq, PacketError.Condition.not_acceptable, null);
        }
    } else {
        // No data form was included so return bad-request error
        sendErrorPacket(iq, PacketError.Condition.bad_request, null);
    }
}
Also used : DataForm(org.xmpp.forms.DataForm) RefreshNodeTask(org.jivesoftware.openfire.pubsub.cluster.RefreshNodeTask)

Example 50 with DataForm

use of org.xmpp.forms.DataForm in project Openfire by igniterealtime.

the class PubSubEngine method createNodeHelper.

/**
     * Checks if the following conditions are satisfied and creates a node
     * - Requester can create nodes
     * - Instant node creation is enabled
     * - Node does not already exist
     * - New node configuration is valid
     *
     * NOTE: This method should not reply to the client
     *
     * @param service
     * @param iq
     * @param childElement
     * @param createElement
     * @return {@link CreateNodeResponse}
     */
private CreateNodeResponse createNodeHelper(PubSubService service, IQ iq, Element childElement, Element createElement) {
    // Get sender of the IQ packet
    JID from = iq.getFrom();
    // Verify that sender has permissions to create nodes
    if (!service.canCreateNode(from) || (!UserManager.getInstance().isRegisteredUser(from) && !isComponent(from))) {
        // The user is not allowed to create nodes so return an error
        return new CreateNodeResponse(PacketError.Condition.forbidden, null, null);
    }
    DataForm completedForm = null;
    CollectionNode parentNode = null;
    String nodeID = createElement.attributeValue("node");
    String newNodeID = nodeID;
    if (nodeID == null) {
        // User requested an instant node
        if (!service.isInstantNodeSupported()) {
            // Instant nodes creation is not allowed so return an error
            Element pubsubError = DocumentHelper.createElement(QName.get("nodeid-required", "http://jabber.org/protocol/pubsub#errors"));
            return new CreateNodeResponse(PacketError.Condition.not_acceptable, pubsubError, null);
        }
        do {
            // Create a new nodeID and make sure that the random generated string does not
            // match an existing node. Probability to match an existing node are very very low
            // but they exist :)
            newNodeID = StringUtils.randomString(15);
        } while (service.getNode(newNodeID) != null);
    }
    boolean collectionType = false;
    // Check if user requested to configure the node (using a data form)
    Element configureElement = childElement.element("configure");
    if (configureElement != null) {
        // Get the data form that contains the parent nodeID
        completedForm = getSentConfigurationForm(configureElement);
        if (completedForm != null) {
            // Calculate newNodeID when new node is affiliated with a Collection
            FormField field = completedForm.getField("pubsub#collection");
            if (field != null) {
                List<String> values = field.getValues();
                if (!values.isEmpty()) {
                    String parentNodeID = values.get(0);
                    Node tempNode = service.getNode(parentNodeID);
                    if (tempNode == null) {
                        // Requested parent node was not found so return an error
                        return new CreateNodeResponse(PacketError.Condition.item_not_found, null, null);
                    } else if (!tempNode.isCollectionNode()) {
                        // Requested parent node is not a collection node so return an error
                        return new CreateNodeResponse(PacketError.Condition.not_acceptable, null, null);
                    }
                    parentNode = (CollectionNode) tempNode;
                }
            }
            field = completedForm.getField("pubsub#node_type");
            if (field != null) {
                // Check if user requested to create a new collection node
                List<String> values = field.getValues();
                if (!values.isEmpty()) {
                    collectionType = "collection".equals(values.get(0));
                }
            }
        }
    }
    // If no parent was defined then use the root collection node
    if (parentNode == null && service.isCollectionNodesSupported()) {
        parentNode = service.getRootCollectionNode();
    }
    // Check that the requested nodeID does not exist
    Node existingNode = service.getNode(newNodeID);
    if (existingNode != null) {
        // There is a conflict since a node with the same ID already exists
        return new CreateNodeResponse(PacketError.Condition.conflict, null, null);
    }
    if (collectionType && !service.isCollectionNodesSupported()) {
        // Cannot create a collection node since the service doesn't support it
        Element pubsubError = DocumentHelper.createElement(QName.get("unsupported", "http://jabber.org/protocol/pubsub#errors"));
        pubsubError.addAttribute("feature", "collections");
        return new CreateNodeResponse(PacketError.Condition.feature_not_implemented, pubsubError, null);
    }
    if (parentNode != null && !collectionType) {
        // Check if requester is allowed to add a new leaf child node to the parent node
        if (!parentNode.isAssociationAllowed(from)) {
            // User is not allowed to add child leaf node to parent node. Return an error.
            return new CreateNodeResponse(PacketError.Condition.forbidden, null, null);
        }
        // Check if number of child leaf nodes has not been exceeded
        if (parentNode.isMaxLeafNodeReached()) {
            // Max number of child leaf nodes has been reached. Return an error.
            Element pubsubError = DocumentHelper.createElement(QName.get("max-nodes-exceeded", "http://jabber.org/protocol/pubsub#errors"));
            return new CreateNodeResponse(PacketError.Condition.conflict, pubsubError, null);
        }
    }
    // Create and configure the node
    boolean conflict = false;
    Node newNode = null;
    try {
        // TODO Assumed that the owner of the subscription is the bare JID of the subscription JID. Waiting StPeter answer for explicit field.
        JID owner = from.asBareJID();
        synchronized (newNodeID.intern()) {
            if (service.getNode(newNodeID) == null) {
                // Create the node
                if (collectionType) {
                    newNode = new CollectionNode(service, parentNode, newNodeID, from);
                } else {
                    newNode = new LeafNode(service, parentNode, newNodeID, from);
                }
                // Add the creator as the node owner
                newNode.addOwner(owner);
                // Configure and save the node to the backend store
                if (completedForm != null) {
                    newNode.configure(completedForm);
                } else {
                    newNode.saveToDB();
                }
                CacheFactory.doClusterTask(new RefreshNodeTask(newNode));
            } else {
                conflict = true;
            }
        }
        if (conflict) {
            // There is a conflict since a node with the same ID already exists
            return new CreateNodeResponse(PacketError.Condition.conflict, null, null);
        } else {
            // Return success to the node owner
            return new CreateNodeResponse(null, null, newNode);
        }
    } catch (NotAcceptableException e) {
        // Node should have at least one owner. Return not-acceptable error.
        return new CreateNodeResponse(PacketError.Condition.not_acceptable, null, null);
    }
}
Also used : JID(org.xmpp.packet.JID) Element(org.dom4j.Element) RefreshNodeTask(org.jivesoftware.openfire.pubsub.cluster.RefreshNodeTask) DataForm(org.xmpp.forms.DataForm) FormField(org.xmpp.forms.FormField)

Aggregations

DataForm (org.xmpp.forms.DataForm)81 FormField (org.xmpp.forms.FormField)67 Element (org.dom4j.Element)23 IQ (org.xmpp.packet.IQ)12 JID (org.xmpp.packet.JID)9 ArrayList (java.util.ArrayList)7 ClientSession (org.jivesoftware.openfire.session.ClientSession)6 HashMap (java.util.HashMap)4 List (java.util.List)4 Group (org.jivesoftware.openfire.group.Group)4 Date (java.util.Date)3 UnauthorizedException (org.jivesoftware.openfire.auth.UnauthorizedException)3 MUCRoom (org.jivesoftware.openfire.muc.MUCRoom)3 UserNotFoundException (org.jivesoftware.openfire.user.UserNotFoundException)3 XStream (com.thoughtworks.xstream.XStream)2 ParseException (java.text.ParseException)2 HashSet (java.util.HashSet)2 Iterator (java.util.Iterator)2 PacketException (org.jivesoftware.openfire.PacketException)2 GroupNotFoundException (org.jivesoftware.openfire.group.GroupNotFoundException)2