diff --git a/magnolia-core/src/main/java/info/magnolia/cms/security/MgnlUserManager.java b/magnolia-core/src/main/java/info/magnolia/cms/security/MgnlUserManager.java index bc028cd..2e8509b 100644 --- a/magnolia-core/src/main/java/info/magnolia/cms/security/MgnlUserManager.java +++ b/magnolia-core/src/main/java/info/magnolia/cms/security/MgnlUserManager.java @@ -33,8 +33,8 @@ */ package info.magnolia.cms.security; -import static info.magnolia.cms.security.SecurityConstants.*; - +import static info.magnolia.cms.security.SecurityConstants.NODE_GROUPS; +import static info.magnolia.cms.security.SecurityConstants.NODE_ROLES; import info.magnolia.cms.core.Content; import info.magnolia.cms.core.HierarchyManager; import info.magnolia.cms.core.Path; @@ -231,21 +231,24 @@ */ @Override public User getUser(final String name) { + //User node names could contain "'" characters, which will lead to a wrong SQL query in: info.magnolia.cms.security.RepositoryBackedSecurityManager.findPrincipalNodeByQuery(String, Session, String, Node) + final String nameEscaped = escapeFullTextExpression(name); + try { return MgnlContext.doInSystemContext(new JCRSessionOp(getRepositoryName()) { @Override public User exec(Session session) throws RepositoryException { - Node priviledgedUserNode = findPrincipalNode(name, session); + Node priviledgedUserNode = findPrincipalNode(nameEscaped, session); return newUserInstance(priviledgedUserNode); } @Override public String toString() { - return "retrieve user " + name; + return "retrieve user " + nameEscaped; } }); } catch (RepositoryException e) { - log.error("Could not retrieve user with name: {}", name, e); + log.error("Could not retrieve user with name: {}", nameEscaped, e); } return null; } @@ -742,4 +745,37 @@ } return users; } + + /** + * See http://wiki.apache.org/jackrabbit/EncodingAndEscaping. + * + * Inspired by: info.magnolia.ui.workbench.search.SearchJcrContainer.escapeFullTextExpression(String) + */ + private String escapeFullTextExpression(final String fulltextExpression) { + String returnValue = escapeIllegalFullTextSearchChars(fulltextExpression); + + return returnValue.replaceAll("'", "''"); + } + + /** + * Within a term, each sensitive char must be escaped by a preceding “\”.
+ * - “-” (minus sign), “+” (plus sign) and “\” (backslash) are escaped if they are the single element of the term
+ * - "()[]{}" (all brackets) are always escaped
+ * - “"” (double quote) is always escape unless it delimits a simple term, i.e "foo -bar"
+ * This method has package visibility for testing purposes. + */ + final String escapeIllegalFullTextSearchChars(final String simpleTerm) { + StringBuilder sb = new StringBuilder(simpleTerm.length()); + + for (int i = 0; i < simpleTerm.length(); i++) { + char ch = simpleTerm.charAt(i); + if (("\\+-".contains(String.valueOf(ch)) && simpleTerm.length() == 1) + || ("()[]{}".contains(String.valueOf(ch))) + || ("\"".contains(String.valueOf(ch)) && (i != 0 && i != simpleTerm.length() - 1))) { + sb.append('\\'); + } + sb.append(ch); + } + return sb.toString(); + } }