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;
}
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;
}
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;
}
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);
}
}
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);
}
}
Aggregations