Commit a9d4767d authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Added escaping of usernames. JM-1403. Reviewer=Pending (Gabriel)

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@10589 b35dd754-fafc-0310-a699-88a17e54d16e
parent 5976f780
...@@ -13,8 +13,9 @@ package org.jivesoftware.openfire.clearspace; ...@@ -13,8 +13,9 @@ package org.jivesoftware.openfire.clearspace;
import org.jivesoftware.openfire.auth.AuthProvider; import org.jivesoftware.openfire.auth.AuthProvider;
import org.jivesoftware.openfire.auth.UnauthorizedException; import org.jivesoftware.openfire.auth.UnauthorizedException;
import static org.jivesoftware.openfire.clearspace.ClearspaceManager.HttpType.GET; import static org.jivesoftware.openfire.clearspace.ClearspaceManager.HttpType.GET;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.openfire.net.SASLAuthentication; import org.jivesoftware.openfire.net.SASLAuthentication;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.xmpp.packet.JID;
/** /**
* The ClearspaceAuthProvider uses the PermissionService web service inside of Clearspace * The ClearspaceAuthProvider uses the PermissionService web service inside of Clearspace
...@@ -60,6 +61,8 @@ public class ClearspaceAuthProvider implements AuthProvider { ...@@ -60,6 +61,8 @@ public class ClearspaceAuthProvider implements AuthProvider {
*/ */
public void authenticate(String username, String password) throws UnauthorizedException { public void authenticate(String username, String password) throws UnauthorizedException {
try { try {
// Un-escape username.
username = JID.unescapeNode(username);
String path = URL_PREFIX + "authenticate/" + username + "/" + password; String path = URL_PREFIX + "authenticate/" + username + "/" + password;
ClearspaceManager.getInstance().executeRequest(GET, path); ClearspaceManager.getInstance().executeRequest(GET, path);
} catch (UnauthorizedException ue) { } catch (UnauthorizedException ue) {
......
...@@ -31,7 +31,6 @@ import java.util.*; ...@@ -31,7 +31,6 @@ import java.util.*;
public class ClearspaceGroupProvider implements GroupProvider { public class ClearspaceGroupProvider implements GroupProvider {
protected static final String URL_PREFIX = "socialGroupService/"; protected static final String URL_PREFIX = "socialGroupService/";
private Boolean readOnly;
private static final String TYPE_ID_OWNER = "0"; private static final String TYPE_ID_OWNER = "0";
private static final String TYPE_ID_MEMBER = "1"; private static final String TYPE_ID_MEMBER = "1";
...@@ -176,13 +175,15 @@ public class ClearspaceGroupProvider implements GroupProvider { ...@@ -176,13 +175,15 @@ public class ClearspaceGroupProvider implements GroupProvider {
for (Element memberElement : membersElement) { for (Element memberElement : membersElement) {
String username = memberElement.element("user").element("username").getText(); String username = memberElement.element("user").element("username").getText();
// Escape username to accept usernames with @ or spaces
String escapedUsername = JID.escapeNode(username);
String typeID = memberElement.element("typeID").getText(); String typeID = memberElement.element("typeID").getText();
if (TYPE_ID_OWNER.equals(typeID)) { if (TYPE_ID_OWNER.equals(typeID)) {
administrators.add(server.createJID(username, null)); administrators.add(server.createJID(escapedUsername, null));
} else if (TYPE_ID_MEMBER.equals(typeID)) { } else if (TYPE_ID_MEMBER.equals(typeID)) {
members.add(server.createJID(username, null)); members.add(server.createJID(escapedUsername, null));
} else { } else {
// nothing to do, waiting for approval // nothing to do, waiting for approval
} }
...@@ -211,10 +212,7 @@ public class ClearspaceGroupProvider implements GroupProvider { ...@@ -211,10 +212,7 @@ public class ClearspaceGroupProvider implements GroupProvider {
// If this is not the first time but these properties have changed, then OF will update it's saved data. // If this is not the first time but these properties have changed, then OF will update it's saved data.
// And this is OK, event if this "getGroup" is to be used in a "change group properties event", the group should // And this is OK, event if this "getGroup" is to be used in a "change group properties event", the group should
// always show the last information. // always show the last information.
Group group = new Group(name, description, members, administrators, properties); return new Group(name, description, members, administrators, properties);
return group;
} }
/** /**
...@@ -245,10 +243,8 @@ public class ClearspaceGroupProvider implements GroupProvider { ...@@ -245,10 +243,8 @@ public class ClearspaceGroupProvider implements GroupProvider {
private Element getGroupMembers(long groupID) throws GroupNotFoundException { private Element getGroupMembers(long groupID) throws GroupNotFoundException {
try { try {
// Gets the members and administrators // Gets the members and administrators
String path = null; String path = URL_PREFIX + "members/" + groupID;
path = URL_PREFIX + "members/" + groupID; return ClearspaceManager.getInstance().executeRequest(GET, path);
Element element = ClearspaceManager.getInstance().executeRequest(GET, path);
return element;
} catch (Exception e) { } catch (Exception e) {
// It is not supported exception, wrap it into a GroupNotFoundException // It is not supported exception, wrap it into a GroupNotFoundException
throw new GroupNotFoundException("Unexpected error", e); throw new GroupNotFoundException("Unexpected error", e);
......
...@@ -169,6 +169,8 @@ public class ClearspaceLockOutProvider implements LockOutProvider { ...@@ -169,6 +169,8 @@ public class ClearspaceLockOutProvider implements LockOutProvider {
// Gets the username // Gets the username
String username = userNode.selectSingleNode("username").getText(); String username = userNode.selectSingleNode("username").getText();
// Escape the username so that it can be used as a JID.
username = JID.escapeNode(username);
// Gets the enabled field // Gets the enabled field
boolean isEnabled = Boolean.valueOf(userNode.selectSingleNode("enabled").getText()); boolean isEnabled = Boolean.valueOf(userNode.selectSingleNode("enabled").getText());
...@@ -205,6 +207,8 @@ public class ClearspaceLockOutProvider implements LockOutProvider { ...@@ -205,6 +207,8 @@ public class ClearspaceLockOutProvider implements LockOutProvider {
} }
try { try {
// Un-escape username.
username = JID.unescapeNode(username);
// Requests the user // Requests the user
String path = USER_URL_PREFIX + "users/" + username; String path = USER_URL_PREFIX + "users/" + username;
// return the response // return the response
......
...@@ -13,10 +13,10 @@ ...@@ -13,10 +13,10 @@
package org.jivesoftware.openfire.clearspace; package org.jivesoftware.openfire.clearspace;
import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.*; import org.apache.commons.httpclient.methods.*;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.dom4j.*; import org.dom4j.*;
import org.dom4j.io.XMPPPacketReader; import org.dom4j.io.XMPPPacketReader;
import org.jivesoftware.openfire.IQResultListener; import org.jivesoftware.openfire.IQResultListener;
...@@ -321,6 +321,8 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM ...@@ -321,6 +321,8 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM
*/ */
public Boolean checkAuthentication(String username, String password) { public Boolean checkAuthentication(String username, String password) {
try { try {
// Un-escape username.
username = JID.unescapeNode(username);
String path = ClearspaceAuthProvider.URL_PREFIX + "authenticate/" + username + "/" + password; String path = ClearspaceAuthProvider.URL_PREFIX + "authenticate/" + username + "/" + password;
executeRequest(GET, path); executeRequest(GET, path);
return true; return true;
...@@ -929,9 +931,11 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM ...@@ -929,9 +931,11 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM
return userIDCache.get(username); return userIDCache.get(username);
} }
// Un-escape username.
String unescapedUsername = JID.unescapeNode(username);
// Gets the user's ID from Clearspace // Gets the user's ID from Clearspace
try { try {
String path = ClearspaceUserProvider.USER_URL_PREFIX + "users/" + username; String path = ClearspaceUserProvider.USER_URL_PREFIX + "users/" + unescapedUsername;
Element element = executeRequest(org.jivesoftware.openfire.clearspace.ClearspaceManager.HttpType.GET, path); Element element = executeRequest(org.jivesoftware.openfire.clearspace.ClearspaceManager.HttpType.GET, path);
Long id = Long.valueOf(WSUtils.getElementText(element.selectSingleNode("return"), "ID")); Long id = Long.valueOf(WSUtils.getElementText(element.selectSingleNode("return"), "ID"));
...@@ -962,8 +966,7 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM ...@@ -962,8 +966,7 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM
if (!server.isLocal(user)) { if (!server.isLocal(user)) {
throw new UserNotFoundException("Cannot load user of remote server: " + user.toString()); throw new UserNotFoundException("Cannot load user of remote server: " + user.toString());
} }
String username = JID.unescapeNode(user.getNode()); return getUserID(user.getNode());
return getUserID(username);
} }
/** /**
...@@ -987,6 +990,9 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM ...@@ -987,6 +990,9 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM
String username = WSUtils.getElementText(element.selectSingleNode("return"), "username"); // TODO: is this right? String username = WSUtils.getElementText(element.selectSingleNode("return"), "username"); // TODO: is this right?
// Escape the username so that it can be used as a JID.
username = JID.escapeNode(username);
usernameCache.put(id, username); usernameCache.put(id, username);
return username; return username;
......
...@@ -10,17 +10,18 @@ ...@@ -10,17 +10,18 @@
*/ */
package org.jivesoftware.openfire.clearspace; package org.jivesoftware.openfire.clearspace;
import org.jivesoftware.openfire.security.SecurityAuditProvider;
import org.jivesoftware.openfire.security.SecurityAuditEvent;
import org.jivesoftware.openfire.security.EventNotFoundException;
import static org.jivesoftware.openfire.clearspace.ClearspaceManager.HttpType.POST;
import org.jivesoftware.util.Log;
import org.dom4j.Document; import org.dom4j.Document;
import org.dom4j.DocumentHelper; import org.dom4j.DocumentHelper;
import org.dom4j.Element; import org.dom4j.Element;
import static org.jivesoftware.openfire.clearspace.ClearspaceManager.HttpType.POST;
import org.jivesoftware.openfire.security.EventNotFoundException;
import org.jivesoftware.openfire.security.SecurityAuditEvent;
import org.jivesoftware.openfire.security.SecurityAuditProvider;
import org.jivesoftware.util.Log;
import org.xmpp.packet.JID;
import java.util.List;
import java.util.Date; import java.util.Date;
import java.util.List;
/** /**
* The ClearspaceSecurityAuditProvider uses the AuditService web service inside of Clearspace * The ClearspaceSecurityAuditProvider uses the AuditService web service inside of Clearspace
...@@ -53,6 +54,8 @@ public class ClearspaceSecurityAuditProvider implements SecurityAuditProvider { ...@@ -53,6 +54,8 @@ public class ClearspaceSecurityAuditProvider implements SecurityAuditProvider {
Document auditDoc = DocumentHelper.createDocument(); Document auditDoc = DocumentHelper.createDocument();
Element rootE = auditDoc.addElement("auditEvent"); Element rootE = auditDoc.addElement("auditEvent");
Element userE = rootE.addElement("username"); Element userE = rootE.addElement("username");
// Un-escape username.
username = JID.unescapeNode(username);
userE.addText(username); userE.addText(username);
Element descE = rootE.addElement("description"); Element descE = rootE.addElement("description");
if (summary != null) { if (summary != null) {
......
...@@ -16,8 +16,6 @@ import org.dom4j.Element; ...@@ -16,8 +16,6 @@ import org.dom4j.Element;
import org.dom4j.Node; import org.dom4j.Node;
import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.openfire.XMPPServer;
import static org.jivesoftware.openfire.clearspace.ClearspaceManager.HttpType.*; import static org.jivesoftware.openfire.clearspace.ClearspaceManager.HttpType.*;
import static org.jivesoftware.openfire.clearspace.WSUtils.getReturn;
import static org.jivesoftware.openfire.clearspace.WSUtils.parseStringArray;
import org.jivesoftware.openfire.user.*; import org.jivesoftware.openfire.user.*;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.xmpp.packet.JID; import org.xmpp.packet.JID;
...@@ -87,6 +85,8 @@ public class ClearspaceUserProvider implements UserProvider { ...@@ -87,6 +85,8 @@ public class ClearspaceUserProvider implements UserProvider {
// adds the username // adds the username
Element usernameE = userE.addElement("username"); Element usernameE = userE.addElement("username");
// Un-escape username.
username = JID.unescapeNode(username);
usernameE.addText(username); usernameE.addText(username);
// adds the name if it is not empty // adds the name if it is not empty
...@@ -151,8 +151,7 @@ public class ClearspaceUserProvider implements UserProvider { ...@@ -151,8 +151,7 @@ public class ClearspaceUserProvider implements UserProvider {
try { try {
String path = USER_URL_PREFIX + "users/count"; String path = USER_URL_PREFIX + "users/count";
Element element = ClearspaceManager.getInstance().executeRequest(GET, path); Element element = ClearspaceManager.getInstance().executeRequest(GET, path);
int count = Integer.valueOf(getReturn(element)); return Integer.valueOf(WSUtils.getReturn(element));
return count;
} catch (Exception e) { } catch (Exception e) {
// It is not supported exception, wrap it into an UnsupportedOperationException // It is not supported exception, wrap it into an UnsupportedOperationException
throw new UnsupportedOperationException("Unexpected error", e); throw new UnsupportedOperationException("Unexpected error", e);
...@@ -179,7 +178,7 @@ public class ClearspaceUserProvider implements UserProvider { ...@@ -179,7 +178,7 @@ public class ClearspaceUserProvider implements UserProvider {
String path = USER_URL_PREFIX + "userNames"; String path = USER_URL_PREFIX + "userNames";
Element element = ClearspaceManager.getInstance().executeRequest(GET, path); Element element = ClearspaceManager.getInstance().executeRequest(GET, path);
return parseStringArray(element); return WSUtils.parseUsernameArray(element);
} catch (Exception e) { } catch (Exception e) {
// It is not supported exception, wrap it into an UnsupportedOperationException // It is not supported exception, wrap it into an UnsupportedOperationException
throw new UnsupportedOperationException("Unexpected error", e); throw new UnsupportedOperationException("Unexpected error", e);
...@@ -388,6 +387,8 @@ public class ClearspaceUserProvider implements UserProvider { ...@@ -388,6 +387,8 @@ public class ClearspaceUserProvider implements UserProvider {
List<Node> userNodes = (List<Node>) element.selectNodes("return"); List<Node> userNodes = (List<Node>) element.selectNodes("return");
for (Node userNode : userNodes) { for (Node userNode : userNodes) {
String username = userNode.selectSingleNode("username").getText(); String username = userNode.selectSingleNode("username").getText();
// Escape the username so that it can be used as a JID.
username = JID.escapeNode(username);
usernames.add(username); usernames.add(username);
} }
...@@ -435,6 +436,8 @@ public class ClearspaceUserProvider implements UserProvider { ...@@ -435,6 +436,8 @@ public class ClearspaceUserProvider implements UserProvider {
List<Node> userNodes = (List<Node>) element.selectNodes("return"); List<Node> userNodes = (List<Node>) element.selectNodes("return");
for (Node userNode : userNodes) { for (Node userNode : userNodes) {
String username = userNode.selectSingleNode("username").getText(); String username = userNode.selectSingleNode("username").getText();
// Escape the username so that it can be used as a JID.
username = JID.escapeNode(username);
usernames.add(username); usernames.add(username);
} }
...@@ -488,7 +491,7 @@ public class ClearspaceUserProvider implements UserProvider { ...@@ -488,7 +491,7 @@ public class ClearspaceUserProvider implements UserProvider {
// See if the is read only // See if the is read only
String path = USER_URL_PREFIX + "isReadOnly"; String path = USER_URL_PREFIX + "isReadOnly";
Element element = ClearspaceManager.getInstance().executeRequest(GET, path); Element element = ClearspaceManager.getInstance().executeRequest(GET, path);
readOnly = Boolean.valueOf(getReturn(element)); readOnly = Boolean.valueOf(WSUtils.getReturn(element));
} catch (Exception e) { } catch (Exception e) {
// if there is a problem, keep it null, maybe in the next call success. // if there is a problem, keep it null, maybe in the next call success.
Log.error("Failed checking #isReadOnly with Clearspace" , e); Log.error("Failed checking #isReadOnly with Clearspace" , e);
...@@ -502,7 +505,7 @@ public class ClearspaceUserProvider implements UserProvider { ...@@ -502,7 +505,7 @@ public class ClearspaceUserProvider implements UserProvider {
* @return a User instance with its information * @return a User instance with its information
*/ */
private User translate(Node responseNode) { private User translate(Node responseNode) {
String username = null; String username;
String name = null; String name = null;
String email = null; String email = null;
Date creationDate = null; Date creationDate = null;
...@@ -513,6 +516,8 @@ public class ClearspaceUserProvider implements UserProvider { ...@@ -513,6 +516,8 @@ public class ClearspaceUserProvider implements UserProvider {
// Gets the username // Gets the username
username = userNode.selectSingleNode("username").getText(); username = userNode.selectSingleNode("username").getText();
// Escape the username so that it can be used as a JID.
username = JID.escapeNode(username);
// Gets the name if it is visible // Gets the name if it is visible
boolean nameVisible = Boolean.valueOf(userNode.selectSingleNode("nameVisible").getText()); boolean nameVisible = Boolean.valueOf(userNode.selectSingleNode("nameVisible").getText());
...@@ -568,13 +573,12 @@ public class ClearspaceUserProvider implements UserProvider { ...@@ -568,13 +573,12 @@ public class ClearspaceUserProvider implements UserProvider {
} }
try { try {
// Un-escape username.
username = JID.unescapeNode(username);
// Requests the user // Requests the user
String path = USER_URL_PREFIX + "users/" + username; String path = USER_URL_PREFIX + "users/" + username;
Element response = ClearspaceManager.getInstance().executeRequest(GET, path);
// return the response // return the response
return response; return ClearspaceManager.getInstance().executeRequest(GET, path);
} catch (UserNotFoundException unfe) { } catch (UserNotFoundException unfe) {
throw unfe; throw unfe;
......
...@@ -12,6 +12,7 @@ package org.jivesoftware.openfire.clearspace; ...@@ -12,6 +12,7 @@ package org.jivesoftware.openfire.clearspace;
import org.dom4j.Element; import org.dom4j.Element;
import org.dom4j.Node; import org.dom4j.Node;
import org.xmpp.packet.JID;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
...@@ -103,6 +104,31 @@ public class WSUtils { ...@@ -103,6 +104,31 @@ public class WSUtils {
return list; return list;
} }
/**
* Parse REST responses of the type String[] that represent usernames, that are XML of the form:
* <p/>
* <something>
* <return>text1</return>
* <return>text2</return>
* <return>text3</return>
* </something>
*
* @param element Element from REST response to be parsed.
* @return An array of strings from the REST response.
*/
protected static List<String> parseUsernameArray(Element element) {
List<String> list = new ArrayList<String>();
@SuppressWarnings("unchecked")
List<Node> nodes = (List<Node>) element.selectNodes("return");
for (Node node : nodes) {
String username = node.getText();
// Escape username.
username = JID.escapeNode(username);
list.add(username);
}
return list;
}
protected static String marshallList(List<String> data) { protected static String marshallList(List<String> data) {
String result = ""; String result = "";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment