You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2017/10/12 12:34:35 UTC
[2/4] syncope git commit: [SYNCOPE-1223] Now allowing FIQL
expressions with escaped , and ;
[SYNCOPE-1223] Now allowing FIQL expressions with escaped , and ;
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/761d1045
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/761d1045
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/761d1045
Branch: refs/heads/master
Commit: 761d1045e5d0ce147271f1780b15d635117e056a
Parents: df35f9c
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Thu Oct 12 13:59:50 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Oct 12 14:27:18 2017 +0200
----------------------------------------------------------------------
.../client/console/commons/AnyDataProvider.java | 63 +++++++---
.../console/panels/AnyDirectoryPanel.java | 3 +-
.../console/panels/search/SearchUtils.java | 126 +++++++++----------
.../api/search/SearchCondConverter.java | 21 ++--
.../api/search/SearchCondVisitor.java | 13 +-
.../api/search/SearchCondConverterTest.java | 11 ++
.../rest/cxf/service/AbstractServiceImpl.java | 2 +
.../apache/syncope/fit/core/SearchITCase.java | 22 ++++
8 files changed, 169 insertions(+), 92 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/761d1045/client/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java
index 20ac7ff..8b3c67b 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java
@@ -21,16 +21,25 @@ package org.apache.syncope.client.console.commons;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.pages.BasePage;
import org.apache.syncope.client.console.rest.AbstractAnyRestClient;
import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class AnyDataProvider<A extends AnyTO> extends DirectoryDataProvider<A> {
private static final long serialVersionUID = 6267494272884913376L;
+ protected static final Logger LOG = LoggerFactory.getLogger(AnyDataProvider.class);
+
private final SortableAnyProviderComparator<A> comparator;
private final AbstractAnyRestClient<A, ?> restClient;
@@ -43,12 +52,15 @@ public class AnyDataProvider<A extends AnyTO> extends DirectoryDataProvider<A> {
private final String type;
+ private final PageReference pageRef;
+
public AnyDataProvider(
final AbstractAnyRestClient<A, ?> restClient,
final int paginatorRows,
final boolean filtered,
final String realm,
- final String type) {
+ final String type,
+ final PageReference pageRef) {
super(paginatorRows);
@@ -74,20 +86,29 @@ public class AnyDataProvider<A extends AnyTO> extends DirectoryDataProvider<A> {
this.realm = realm;
this.type = type;
+ this.pageRef = pageRef;
}
@Override
public Iterator<A> iterator(final long first, final long count) {
- List<A> result;
-
- final int page = ((int) first / paginatorRows);
-
- if (filtered) {
- result = fiql == null
- ? Collections.<A>emptyList()
- : restClient.search(realm, fiql, (page < 0 ? 0 : page) + 1, paginatorRows, getSort(), type);
- } else {
- result = restClient.search(realm, null, (page < 0 ? 0 : page) + 1, paginatorRows, getSort(), type);
+ List<A> result = Collections.emptyList();
+
+ try {
+ final int page = ((int) first / paginatorRows);
+
+ if (filtered) {
+ result = fiql == null
+ ? Collections.<A>emptyList()
+ : restClient.search(realm, fiql, (page < 0 ? 0 : page) + 1, paginatorRows, getSort(), type);
+ } else {
+ result = restClient.search(realm, null, (page < 0 ? 0 : page) + 1, paginatorRows, getSort(), type);
+ }
+ } catch (Exception e) {
+ LOG.error("While searching with FIQL {}", fiql, e);
+ SyncopeConsoleSession.get().error(e.getMessage());
+
+ ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(
+ RequestCycle.get().find(AjaxRequestTarget.class));
}
Collections.sort(result, comparator);
@@ -96,12 +117,20 @@ public class AnyDataProvider<A extends AnyTO> extends DirectoryDataProvider<A> {
@Override
public long size() {
- long result;
-
- if (filtered) {
- result = fiql == null ? 0 : restClient.searchCount(realm, fiql, type);
- } else {
- result = restClient.searchCount(realm, null, type);
+ long result = 0;
+
+ try {
+ if (filtered) {
+ result = fiql == null ? 0 : restClient.searchCount(realm, fiql, type);
+ } else {
+ result = restClient.searchCount(realm, null, type);
+ }
+ } catch (Exception e) {
+ LOG.error("While requesting for size() with FIQL {}", fiql, e);
+ SyncopeConsoleSession.get().error(e.getMessage());
+
+ ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(
+ RequestCycle.get().find(AjaxRequestTarget.class));
}
return result;
http://git-wip-us.apache.org/repos/asf/syncope/blob/761d1045/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
index 828a698..da58347 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
@@ -211,8 +211,7 @@ public abstract class AnyDirectoryPanel<A extends AnyTO, E extends AbstractAnyRe
@Override
protected AnyDataProvider<A> dataProvider() {
- final AnyDataProvider<A> dp = new AnyDataProvider<>(restClient, rows, filtered, realm, type);
- return dp.setFIQL(this.fiql);
+ return new AnyDataProvider<>(restClient, rows, filtered, realm, type, pageRef).setFIQL(this.fiql);
}
public void search(final String fiql, final AjaxRequestTarget target) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/761d1045/client/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchUtils.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchUtils.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchUtils.java
index d7f4e1f..68ac17f 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchUtils.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchUtils.java
@@ -55,48 +55,46 @@ public final class SearchUtils implements Serializable {
}
public static Map<String, List<SearchClause>> getSearchClauses(final Map<String, String> fiql) {
- final Map<String, List<SearchClause>> res = new HashMap<>();
- if (fiql != null && !fiql.isEmpty()) {
- for (Map.Entry<String, String> entry : fiql.entrySet()) {
- res.put(entry.getKey(), getSearchClauses(
- entry.getValue().replaceAll(getTypeConditionPattern(entry.getKey()).pattern(), "")));
- }
+ Map<String, List<SearchClause>> clauses = new HashMap<>();
+ for (Map.Entry<String, String> entry : fiql.entrySet()) {
+ clauses.put(entry.getKey(), getSearchClauses(
+ entry.getValue().replaceAll(getTypeConditionPattern(entry.getKey()).pattern(), "")));
}
- return res;
+ return clauses;
}
public static List<SearchClause> getSearchClauses(final String fiql) {
- final List<SearchClause> res = new ArrayList<>();
+ List<SearchClause> clauses = new ArrayList<>();
if (StringUtils.isNotBlank(fiql)) {
try {
SyncopeFiqlParser<SearchBean> fiqlParser = new SyncopeFiqlParser<>(
SearchBean.class, AbstractFiqlSearchConditionBuilder.CONTEXTUAL_PROPERTIES);
- res.addAll(getSearchClauses(fiqlParser.parse(fiql)));
+ clauses.addAll(getSearchClauses(fiqlParser.parse(fiql)));
} catch (Exception e) {
LOG.error("Unparseable FIQL expression '{}'", fiql, e);
}
}
- return res;
+ return clauses;
}
private static List<SearchClause> getSearchClauses(final SearchCondition<SearchBean> sc) {
- List<SearchClause> res = new ArrayList<>();
+ List<SearchClause> clauses = new ArrayList<>();
if (sc.getStatement() == null) {
- res.addAll(getCompoundSearchClause(sc));
+ clauses.addAll(getCompoundSearchClauses(sc));
} else {
- res.add(getPrimitiveSearchClause(sc));
+ clauses.add(getPrimitiveSearchClause(sc));
}
- return res;
+ return clauses;
}
- private static List<SearchClause> getCompoundSearchClause(final SearchCondition<SearchBean> sc) {
- List<SearchClause> res = new ArrayList<>();
+ private static List<SearchClause> getCompoundSearchClauses(final SearchCondition<SearchBean> sc) {
+ List<SearchClause> clauses = new ArrayList<>();
for (SearchCondition<SearchBean> searchCondition : sc.getSearchConditions()) {
if (searchCondition.getStatement() == null) {
- res.addAll(getCompoundSearchClause(searchCondition));
+ clauses.addAll(getCompoundSearchClauses(searchCondition));
} else {
SearchClause clause = getPrimitiveSearchClause(searchCondition);
if (sc.getConditionType() == ConditionType.AND) {
@@ -105,43 +103,43 @@ public final class SearchUtils implements Serializable {
if (sc.getConditionType() == ConditionType.OR) {
clause.setOperator(SearchClause.Operator.OR);
}
- res.add(clause);
+ clauses.add(clause);
}
}
- return res;
+ return clauses;
}
private static SearchClause getPrimitiveSearchClause(final SearchCondition<SearchBean> sc) {
- SearchClause res = new SearchClause();
+ SearchClause clause = new SearchClause();
String property = sc.getCondition().getKeySet().iterator().next();
- res.setProperty(property);
- String value = sc.getCondition().get(property);
- res.setValue(value);
+ clause.setProperty(property);
+ String value = sc.getCondition().get(property).replace("%252C", ",").replace("%253B", ";");
+ clause.setValue(value);
LOG.debug("Condition: " + sc.getCondition());
if (SpecialAttr.ROLES.toString().equals(property)) {
- res.setType(SearchClause.Type.ROLE_MEMBERSHIP);
- res.setProperty(value);
+ clause.setType(SearchClause.Type.ROLE_MEMBERSHIP);
+ clause.setProperty(value);
} else if (SpecialAttr.RELATIONSHIPS.toString().equals(property)) {
- res.setType(SearchClause.Type.RELATIONSHIP);
- res.setProperty(value);
+ clause.setType(SearchClause.Type.RELATIONSHIP);
+ clause.setProperty(value);
} else if (SpecialAttr.RELATIONSHIP_TYPES.toString().equals(property)) {
- res.setType(SearchClause.Type.RELATIONSHIP);
- res.setProperty(value);
+ clause.setType(SearchClause.Type.RELATIONSHIP);
+ clause.setProperty(value);
} else if (SpecialAttr.GROUPS.toString().equals(property)) {
- res.setType(SearchClause.Type.GROUP_MEMBERSHIP);
- res.setProperty(value);
+ clause.setType(SearchClause.Type.GROUP_MEMBERSHIP);
+ clause.setProperty(value);
} else if (SpecialAttr.RESOURCES.toString().equals(property)) {
- res.setType(SearchClause.Type.RESOURCE);
- res.setProperty(value);
+ clause.setType(SearchClause.Type.RESOURCE);
+ clause.setProperty(value);
} else if (SpecialAttr.MEMBER.toString().equals(property)) {
- res.setType(SearchClause.Type.GROUP_MEMBER);
- res.setProperty(value);
+ clause.setType(SearchClause.Type.GROUP_MEMBER);
+ clause.setProperty(value);
} else {
- res.setType(SearchClause.Type.ATTRIBUTE);
+ clause.setType(SearchClause.Type.ATTRIBUTE);
}
ConditionType ct = sc.getConditionType();
@@ -156,45 +154,45 @@ public final class SearchUtils implements Serializable {
switch (ct) {
case EQUALS:
if (SpecialAttr.RELATIONSHIP_TYPES.toString().equals(property)) {
- res.setComparator(SpecialAttr.NULL.toString().equals(value)
+ clause.setComparator(SpecialAttr.NULL.toString().equals(value)
? SearchClause.Comparator.EQUALS : SearchClause.Comparator.IS_NULL);
} else {
- res.setComparator(SpecialAttr.NULL.toString().equals(value)
+ clause.setComparator(SpecialAttr.NULL.toString().equals(value)
? SearchClause.Comparator.IS_NULL : SearchClause.Comparator.EQUALS);
}
break;
case NOT_EQUALS:
if (SpecialAttr.RELATIONSHIP_TYPES.toString().equals(property)) {
- res.setComparator(SpecialAttr.NULL.toString().equals(value)
+ clause.setComparator(SpecialAttr.NULL.toString().equals(value)
? SearchClause.Comparator.NOT_EQUALS : SearchClause.Comparator.IS_NOT_NULL);
} else {
- res.setComparator(SpecialAttr.NULL.toString().equals(value)
+ clause.setComparator(SpecialAttr.NULL.toString().equals(value)
? SearchClause.Comparator.IS_NOT_NULL : SearchClause.Comparator.NOT_EQUALS);
}
break;
case GREATER_OR_EQUALS:
- res.setComparator(SearchClause.Comparator.GREATER_OR_EQUALS);
+ clause.setComparator(SearchClause.Comparator.GREATER_OR_EQUALS);
break;
case GREATER_THAN:
- res.setComparator(SearchClause.Comparator.GREATER_THAN);
+ clause.setComparator(SearchClause.Comparator.GREATER_THAN);
break;
case LESS_OR_EQUALS:
- res.setComparator(SearchClause.Comparator.LESS_OR_EQUALS);
+ clause.setComparator(SearchClause.Comparator.LESS_OR_EQUALS);
break;
case LESS_THAN:
- res.setComparator(SearchClause.Comparator.LESS_THAN);
+ clause.setComparator(SearchClause.Comparator.LESS_THAN);
break;
default:
break;
}
- return res;
+ return clause;
}
public static String buildFIQL(final List<SearchClause> clauses, final AbstractFiqlSearchConditionBuilder builder) {
@@ -216,17 +214,19 @@ public final class SearchUtils implements Serializable {
prevCondition = condition;
if (clause.getType() != null) {
+ String value = clause.getValue() == null
+ ? null
+ : clause.getValue().replace(",", "%252C").replace(";", "%253B");
+
switch (clause.getType()) {
case GROUP_MEMBER:
switch (clause.getComparator()) {
case EQUALS:
- condition = ((GroupFiqlSearchConditionBuilder) builder).
- withMembers(clause.getValue());
+ condition = ((GroupFiqlSearchConditionBuilder) builder).withMembers(value);
break;
case NOT_EQUALS:
- condition = ((GroupFiqlSearchConditionBuilder) builder).
- withoutMembers(clause.getValue());
+ condition = ((GroupFiqlSearchConditionBuilder) builder).withoutMembers(value);
break;
default:
@@ -275,35 +275,35 @@ public final class SearchUtils implements Serializable {
case LESS_THAN:
condition = isLong
- ? property.lessThan(NumberUtils.toLong(clause.getValue()))
- : property.lexicalBefore(clause.getValue());
+ ? property.lessThan(NumberUtils.toLong(value))
+ : property.lexicalBefore(value);
break;
case LESS_OR_EQUALS:
condition = isLong
- ? property.lessOrEqualTo(NumberUtils.toLong(clause.getValue()))
- : property.lexicalNotAfter(clause.getValue());
+ ? property.lessOrEqualTo(NumberUtils.toLong(value))
+ : property.lexicalNotAfter(value);
break;
case GREATER_THAN:
condition = isLong
- ? property.greaterThan(NumberUtils.toLong(clause.getValue()))
- : property.lexicalAfter(clause.getValue());
+ ? property.greaterThan(NumberUtils.toLong(value))
+ : property.lexicalAfter(value);
break;
case GREATER_OR_EQUALS:
condition = isLong
- ? property.greaterOrEqualTo(NumberUtils.toLong(clause.getValue()))
- : property.lexicalNotBefore(clause.getValue());
+ ? property.greaterOrEqualTo(NumberUtils.toLong(value))
+ : property.lexicalNotBefore(value);
break;
case NOT_EQUALS:
- condition = property.notEqualTolIgnoreCase(clause.getValue());
+ condition = property.notEqualTolIgnoreCase(value);
break;
case EQUALS:
default:
- condition = property.equalToIgnoreCase(clause.getValue());
+ condition = property.equalToIgnoreCase(value);
break;
}
}
@@ -340,11 +340,11 @@ public final class SearchUtils implements Serializable {
break;
case EQUALS:
condition = ((UserFiqlSearchConditionBuilder) builder).
- inRelationships(clause.getValue());
+ inRelationships(value);
break;
case NOT_EQUALS:
condition = ((UserFiqlSearchConditionBuilder) builder).
- notInRelationships(clause.getValue());
+ notInRelationships(value);
break;
default:
break;
@@ -361,11 +361,11 @@ public final class SearchUtils implements Serializable {
break;
case EQUALS:
condition = ((AnyObjectFiqlSearchConditionBuilder) builder).
- inRelationships(clause.getValue());
+ inRelationships(value);
break;
case NOT_EQUALS:
condition = ((AnyObjectFiqlSearchConditionBuilder) builder).
- notInRelationships(clause.getValue());
+ notInRelationships(value);
break;
default:
break;
http://git-wip-us.apache.org/repos/asf/syncope/blob/761d1045/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondConverter.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondConverter.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondConverter.java
index f07453f..1ec0f6f 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondConverter.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondConverter.java
@@ -18,8 +18,11 @@
*/
package org.apache.syncope.core.persistence.api.search;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.cxf.jaxrs.ext.search.SearchBean;
+import org.apache.cxf.jaxrs.ext.search.SearchCondition;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.search.AbstractFiqlSearchConditionBuilder;
import org.apache.syncope.common.lib.search.SyncopeFiqlParser;
@@ -34,25 +37,27 @@ public final class SearchCondConverter {
/**
* Parses a FIQL expression into Syncope's <tt>SearchCond</tt>, using CXF's <tt>FiqlParser</tt>.
*
- * @param fiqlExpression FIQL string
+ * @param fiql FIQL string
* @param realms optional realm to provide to {@link SearchCondVisitor}
* @return {@link SearchCond} instance for given FIQL expression
* @see SyncopeFiqlParser
*/
- public static SearchCond convert(final String fiqlExpression, final String... realms) {
- SyncopeFiqlParser<SearchBean> fiqlParser = new SyncopeFiqlParser<>(
+ public static SearchCond convert(final String fiql, final String... realms) {
+ SyncopeFiqlParser<SearchBean> parser = new SyncopeFiqlParser<>(
SearchBean.class, AbstractFiqlSearchConditionBuilder.CONTEXTUAL_PROPERTIES);
try {
- SearchCondVisitor searchCondVisitor = new SearchCondVisitor();
+ SearchCondVisitor visitor = new SearchCondVisitor();
if (realms != null && realms.length > 0) {
- searchCondVisitor.setRealm(realms[0]);
+ visitor.setRealm(realms[0]);
}
- searchCondVisitor.visit(fiqlParser.parse(fiqlExpression));
- return searchCondVisitor.getQuery();
+ SearchCondition<SearchBean> sc = parser.parse(URLDecoder.decode(fiql, StandardCharsets.UTF_8.name()));
+ sc.accept(visitor);
+
+ return visitor.getQuery();
} catch (Exception e) {
SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidSearchExpression);
- sce.getElements().add(fiqlExpression);
+ sce.getElements().add(fiql);
sce.getElements().add(ExceptionUtils.getRootCauseMessage(e));
throw sce;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/761d1045/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java
index 2af6f25..18d5766 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java
@@ -18,6 +18,9 @@
*/
package org.apache.syncope.core.persistence.api.search;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@@ -73,8 +76,14 @@ public class SearchCondVisitor extends AbstractSearchConditionVisitor<SearchBean
String name = getRealPropertyName(sc.getStatement().getProperty());
Optional<SpecialAttr> specialAttrName = SpecialAttr.fromString(name);
- String value = SearchUtils.toSqlWildcardString(sc.getStatement().getValue().toString(), false).
- replaceAll("\\\\_", "_");
+ String value = null;
+ try {
+ value = SearchUtils.toSqlWildcardString(
+ URLDecoder.decode(sc.getStatement().getValue().toString(), StandardCharsets.UTF_8.name()), false).
+ replaceAll("\\\\_", "_");
+ } catch (UnsupportedEncodingException e) {
+ throw new IllegalArgumentException("While decoding " + sc.getStatement().getValue(), e);
+ }
Optional<SpecialAttr> specialAttrValue = SpecialAttr.fromString(value);
AttributeCond attributeCond = createAttributeCond(name);
http://git-wip-us.apache.org/repos/asf/syncope/blob/761d1045/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java b/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
index 6d5981e..10e229f 100644
--- a/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
+++ b/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
@@ -305,4 +305,15 @@ public class SearchCondConverterTest {
assertEquals(orCond, SearchCondConverter.convert(fiql));
}
+ @Test
+ public void issueSYNCOPE1223() {
+ String fiql = new UserFiqlSearchConditionBuilder().is("ctype").equalTo("ou=sample%252Co=isp").query();
+
+ AttributeCond cond = new AttributeCond(AttributeCond.Type.EQ);
+ cond.setSchema("ctype");
+ cond.setExpression("ou=sample,o=isp");
+
+ assertEquals(SearchCond.getLeafCond(cond), SearchCondConverter.convert(fiql));
+ }
+
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/761d1045/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
index 4ca01dc..a040960 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
@@ -30,6 +30,7 @@ import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.cxf.jaxrs.ext.MessageContext;
import org.apache.cxf.jaxrs.ext.search.SearchBean;
import org.apache.cxf.jaxrs.ext.search.SearchCondition;
@@ -161,6 +162,7 @@ abstract class AbstractServiceImpl implements JAXRSService {
SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidSearchExpression);
sce.getElements().add(fiql);
+ sce.getElements().add(ExceptionUtils.getRootCauseMessage(e));
throw sce;
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/761d1045/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
index e8002a6..0677ad7 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
@@ -28,7 +28,9 @@ import javax.ws.rs.core.Response;
import org.apache.syncope.client.lib.SyncopeClient;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.patch.AnyObjectPatch;
+import org.apache.syncope.common.lib.patch.AttrPatch;
import org.apache.syncope.common.lib.patch.MembershipPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
import org.apache.syncope.common.lib.to.AnyObjectTO;
import org.apache.syncope.common.lib.to.AnyTypeTO;
import org.apache.syncope.common.lib.to.PagedResult;
@@ -471,4 +473,24 @@ public class SearchITCase extends AbstractITCase {
build());
assertNotEquals(0, users.getTotalCount());
}
+
+ @Test
+ public void issueSYNCOPE1223() {
+ UserPatch patch = new UserPatch();
+ patch.setKey("vivaldi");
+ patch.getPlainAttrs().add(new AttrPatch.Builder().attrTO(attrTO("ctype", "ou=sample,o=isp")).build());
+ userService.update(patch);
+
+ try {
+ PagedResult<UserTO> users = userService.search(new AnyQuery.Builder().fiql(
+ SyncopeClient.getUserSearchConditionBuilder().is("ctype").equalTo("ou=sample%252Co=isp").query()).
+ build());
+ assertEquals(1, users.getTotalCount());
+ assertEquals("vivaldi", users.getResult().get(0).getUsername());
+ } finally {
+ patch.getPlainAttrs().clear();
+ patch.getPlainAttrs().add(new AttrPatch.Builder().attrTO(attrTO("ctype", "F")).build());
+ userService.update(patch);
+ }
+ }
}