Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,16 @@

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.core.persistence.api.attrvalue.PlainAttrValidationManager;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
Expand All @@ -44,6 +48,7 @@
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
import org.apache.syncope.core.persistence.api.utils.RealmUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
Expand All @@ -54,6 +59,10 @@

public abstract class AbstractAnySearchDAO extends AbstractSearchDAO implements AnySearchDAO {

public record AdminRealmsFilter<T>(T filter, Set<Pair<AnyTypeKind, String>> managed) {

}

protected static final Logger LOG = LoggerFactory.getLogger(AnySearchDAO.class);

private static final Set<String> ORDER_BY_NOT_ALLOWED = Set.of(
Expand Down Expand Up @@ -126,6 +135,37 @@ public <A extends Any> List<A> findByDerAttrValue(
return conditions.isEmpty() ? List.of() : search(SearchCond.and(conditions), anyTypeKind);
}

protected <T> AdminRealmsFilter<T> processRealms(
final Realm base,
final boolean recursive,
final Set<String> adminRealms,
final Function<Set<String>, T> filterBuilder) {

Set<String> realmKeys = new HashSet<>();
Set<Pair<AnyTypeKind, String>> managed = new HashSet<>();

adminRealms.forEach(realmPath -> RealmUtils.ManagerRealm.of(realmPath).ifPresentOrElse(
realm -> managed.add(Pair.of(realm.kind(), realm.anyKey())),
() -> {
Realm realm = realmSearchDAO.findByFullPath(realmPath).orElseThrow(() -> {
SyncopeClientException noRealm = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
noRealm.getElements().add("Invalid realm specified: " + realmPath);
return noRealm;
});

if (recursive) {
realmKeys.addAll(realmSearchDAO.findDescendants(realm.getFullPath(), base.getFullPath()).
stream().map(Realm::getKey).toList());
} else {
if (RealmUtils.subtree(realm.getFullPath(), base.getFullPath())) {
realmKeys.add(realm.getKey());
}
}
}));

return new AdminRealmsFilter<>(filterBuilder.apply(realmKeys), managed);
}

protected abstract long doCount(
Realm base, boolean recursive, Set<String> adminRealms, SearchCond cond, AnyTypeKind kind);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,9 @@
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.AttrSchemaType;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.rest.api.service.JAXRSService;
import org.apache.syncope.core.persistence.api.attrvalue.PlainAttrValidationManager;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
Expand All @@ -60,7 +57,6 @@
import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
import org.apache.syncope.core.persistence.api.entity.PlainSchema;
import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.persistence.api.utils.RealmUtils;
import org.apache.syncope.core.persistence.common.dao.AbstractAnySearchDAO;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
Expand All @@ -70,10 +66,6 @@
*/
abstract class AbstractJPAAnySearchDAO extends AbstractAnySearchDAO {

protected record AdminRealmsFilter(AnySearchNode.Leaf filter, Set<Pair<AnyTypeKind, String>> managed) {

}

protected record QueryInfo(AnySearchNode node, Set<String> plainSchemas) {

}
Expand Down Expand Up @@ -620,52 +612,24 @@ protected AnySearchNode getQuery(
};
}

protected AnySearchNode.Leaf buildAdminRealmsFilter(
final Set<String> realmKeys,
final SearchSupport svs,
final List<Object> parameters) {

if (realmKeys.isEmpty()) {
return new AnySearchNode.Leaf(defaultSV(svs), StringUtils.substringAfter(anyId(svs), '.') + " IS NOT NULL");
}

String realmKeysArg = realmKeys.stream().
map(realmKey -> "?" + setParameter(parameters, realmKey)).
collect(Collectors.joining(","));
return new AnySearchNode.Leaf(defaultSV(svs), "realm_id IN (" + realmKeysArg + ")");
}

protected AdminRealmsFilter getAdminRealmsFilter(
protected AdminRealmsFilter<AnySearchNode.Leaf> getAdminRealmsFilter(
final Realm base,
final boolean recursive,
final Set<String> adminRealms,
final List<Object> parameters,
final SearchSupport svs) {

Set<String> realmKeys = new HashSet<>();
Set<Pair<AnyTypeKind, String>> managed = new HashSet<>();

if (recursive) {
adminRealms.forEach(realmPath -> RealmUtils.ManagerRealm.of(realmPath).ifPresentOrElse(
realm -> managed.add(Pair.of(realm.kind(), realm.anyKey())),
() -> {
Realm realm = realmSearchDAO.findByFullPath(realmPath).orElseThrow(() -> {
SyncopeClientException noRealm =
SyncopeClientException.build(ClientExceptionType.InvalidRealm);
noRealm.getElements().add("Invalid realm specified: " + realmPath);
return noRealm;
});

realmKeys.addAll(realmSearchDAO.findDescendants(realm.getFullPath(), base.getFullPath()).
stream().map(Realm::getKey).toList());
}));
} else {
if (RealmUtils.SubtreePredicate.of(adminRealms).test(base.getFullPath())) {
realmKeys.add(base.getKey());
return processRealms(base, recursive, adminRealms, realmKeys -> {
if (realmKeys.isEmpty()) {
return new AnySearchNode.Leaf(
defaultSV(svs), StringUtils.substringAfter(anyId(svs), '.') + " IS NOT NULL");
}
}

return new AdminRealmsFilter(buildAdminRealmsFilter(realmKeys, svs, parameters), managed);
String realmKeysArg = realmKeys.stream().
map(realmKey -> "?" + setParameter(parameters, realmKey)).
collect(Collectors.joining(","));
return new AnySearchNode.Leaf(defaultSV(svs), "realm_id IN (" + realmKeysArg + ")");
});
}

protected void visitNode(
Expand Down Expand Up @@ -771,7 +735,8 @@ protected long doCount(
SearchSupport svs = new SearchViewSupport(kind);

// 1. get admin realms filter
AdminRealmsFilter filter = getAdminRealmsFilter(base, recursive, adminRealms, parameters, svs);
AdminRealmsFilter<AnySearchNode.Leaf> filter =
getAdminRealmsFilter(base, recursive, adminRealms, parameters, svs);

// 2. transform search condition
QueryInfo queryInfo = getQuery(
Expand Down Expand Up @@ -936,7 +901,8 @@ protected <T extends Any> List<T> doSearch(
SearchSupport svs = new SearchViewSupport(kind);

// 1. get admin realms filter
AdminRealmsFilter filter = getAdminRealmsFilter(base, recursive, adminRealms, parameters, svs);
AdminRealmsFilter<AnySearchNode.Leaf> filter =
getAdminRealmsFilter(base, recursive, adminRealms, parameters, svs);

// 2. transform search condition
QueryInfo queryInfo = getQuery(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import java.util.stream.Stream;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.text.TextStringBuilder;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.SyncopeConstants;
Expand Down Expand Up @@ -62,7 +61,6 @@
import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
import org.apache.syncope.core.persistence.api.entity.PlainSchema;
import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.persistence.api.utils.RealmUtils;
import org.apache.syncope.core.persistence.common.dao.AbstractAnySearchDAO;
import org.apache.syncope.core.persistence.neo4j.dao.repo.AnyRepoExt;
import org.apache.syncope.core.persistence.neo4j.entity.AbstractAny;
Expand All @@ -88,10 +86,6 @@

public class Neo4jAnySearchDAO extends AbstractAnySearchDAO {

protected record AdminRealmsFilter(String filter, Set<Pair<AnyTypeKind, String>> managed) {

}

protected record AnyCondQuery(String query, String field) {

}
Expand Down Expand Up @@ -180,47 +174,19 @@ protected boolean isPatternMatch(final String clause) {
return clause.indexOf('*') != -1;
}

protected String buildAdminRealmsFilter(
final Set<String> realmKeys,
final Map<String, Object> parameters) {

if (realmKeys.isEmpty()) {
return "(n)-[]-(:" + Neo4jRealm.NODE + ")";
}

return "(n)-[]-(r:" + Neo4jRealm.NODE + ") WHERE r.id IN $" + setParameter(parameters, realmKeys);
}

protected AdminRealmsFilter getAdminRealmsFilter(
protected AdminRealmsFilter<String> getAdminRealmsFilter(
final Realm base,
final boolean recursive,
final Set<String> adminRealms,
final Map<String, Object> parameters) {

Set<String> realmKeys = new HashSet<>();
Set<Pair<AnyTypeKind, String>> managed = new HashSet<>();

if (recursive) {
adminRealms.forEach(realmPath -> RealmUtils.ManagerRealm.of(realmPath).ifPresentOrElse(
realm -> managed.add(Pair.of(realm.kind(), realm.anyKey())),
() -> {
Realm realm = realmSearchDAO.findByFullPath(realmPath).orElseThrow(() -> {
SyncopeClientException noRealm =
SyncopeClientException.build(ClientExceptionType.InvalidRealm);
noRealm.getElements().add("Invalid realm specified: " + realmPath);
return noRealm;
});

realmKeys.addAll(realmSearchDAO.findDescendants(realm.getFullPath(), base.getFullPath()).
stream().map(Realm::getKey).toList());
}));
} else {
if (RealmUtils.SubtreePredicate.of(adminRealms).test(base.getFullPath())) {
realmKeys.add(base.getKey());
return processRealms(base, recursive, adminRealms, realmKeys -> {
if (realmKeys.isEmpty()) {
return "(n)-[]-(:" + Neo4jRealm.NODE + ")";
}
}

return new AdminRealmsFilter(buildAdminRealmsFilter(realmKeys, parameters), managed);
return "(n)-[]-(r:" + Neo4jRealm.NODE + ") WHERE r.id IN $" + setParameter(parameters, realmKeys);
});
}

protected String getQuery(
Expand Down Expand Up @@ -910,7 +876,7 @@ protected long doCount(

Map<String, Object> parameters = new HashMap<>();

AdminRealmsFilter filter = getAdminRealmsFilter(base, recursive, adminRealms, parameters);
AdminRealmsFilter<String> filter = getAdminRealmsFilter(base, recursive, adminRealms, parameters);

// 1. get the query string from the search condition
QueryInfo queryInfo = getQuery(
Expand Down Expand Up @@ -979,7 +945,7 @@ protected <T extends Any> List<T> doSearch(

Map<String, Object> parameters = new HashMap<>();

AdminRealmsFilter filter = getAdminRealmsFilter(base, recursive, adminRealms, parameters);
AdminRealmsFilter<String> filter = getAdminRealmsFilter(base, recursive, adminRealms, parameters);

// 1. get the query string from the search condition
QueryInfo queryInfo = getQuery(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,14 @@
import co.elastic.clients.json.JsonData;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.AttrSchemaType;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.rest.api.service.JAXRSService;
import org.apache.syncope.core.persistence.api.attrvalue.PlainAttrValidationManager;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
Expand All @@ -74,7 +70,6 @@
import org.apache.syncope.core.persistence.api.entity.PlainSchema;
import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.persistence.api.utils.FormatUtils;
import org.apache.syncope.core.persistence.api.utils.RealmUtils;
import org.apache.syncope.core.persistence.common.dao.AbstractAnySearchDAO;
import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.apache.syncope.ext.elasticsearch.client.ElasticsearchUtils;
Expand All @@ -87,10 +82,6 @@
*/
public class ElasticsearchAnySearchDAO extends AbstractAnySearchDAO {

protected record AdminRealmsFilter(Optional<Query> query, Set<Pair<AnyTypeKind, String>> managed) {

}

protected static final Set<String> ID_PROPS = Set.of("key", "id", "_id");

protected final ElasticsearchClient client;
Expand Down Expand Up @@ -123,44 +114,22 @@ public ElasticsearchAnySearchDAO(
this.indexMaxResultWindow = indexMaxResultWindow;
}

protected AdminRealmsFilter getAdminRealmsFilter(
protected AdminRealmsFilter<Optional<Query>> getAdminRealmsFilter(
final Realm base,
final boolean recursive,
final Set<String> adminRealms) {

Set<Pair<AnyTypeKind, String>> managed = new HashSet<>();
List<Query> queries = new ArrayList<>();

if (recursive) {
adminRealms.forEach(realmPath -> RealmUtils.ManagerRealm.of(realmPath).ifPresentOrElse(
realm -> managed.add(Pair.of(realm.kind(), realm.anyKey())),
() -> {
Realm realm = realmSearchDAO.findByFullPath(realmPath).orElseThrow(() -> {
SyncopeClientException noRealm =
SyncopeClientException.build(ClientExceptionType.InvalidRealm);
noRealm.getElements().add("Invalid realm specified: " + realmPath);
return noRealm;
});

realmSearchDAO.findDescendants(realm.getFullPath(), base.getFullPath()).
stream().map(Realm::getKey).forEach(descendant -> queries.add(
new Query.Builder().term(QueryBuilders.term().
field("realm").value(descendant).caseInsensitive(false).build()).
build()));
}));
} else {
if (RealmUtils.SubtreePredicate.of(adminRealms).test(base.getFullPath())) {
queries.add(new Query.Builder().term(QueryBuilders.term().
field("realm").value(base.getKey()).caseInsensitive(false).build()).
build());
return processRealms(base, recursive, adminRealms, realmKeys -> {
if (realmKeys.isEmpty()) {
return Optional.empty();
}
}

return new AdminRealmsFilter(
managed.isEmpty()
? Optional.of(new Query.Builder().disMax(QueryBuilders.disMax().queries(queries).build()).build())
: Optional.empty(),
managed);
List<Query> queries = realmKeys.stream().
map(realm -> new Query.Builder().term(QueryBuilders.term().
field("realm").value(realm).caseInsensitive(false).build()).
build()).toList();
return Optional.of(new Query.Builder().disMax(QueryBuilders.disMax().queries(queries).build()).build());
});
}

protected Query getQuery(
Expand All @@ -184,13 +153,13 @@ protected Query getQuery(
build();
}
} else {
AdminRealmsFilter filter = getAdminRealmsFilter(base, recursive, adminRealms);
AdminRealmsFilter<Optional<Query>> filter = getAdminRealmsFilter(base, recursive, adminRealms);
query = getQuery(buildEffectiveCond(cond, filter.managed(), kind), kind);

if (filter.query().isPresent()) {
if (filter.filter().isPresent()) {
query = new Query.Builder().bool(
QueryBuilders.bool().
filter(filter.query().get()).
filter(filter.filter().get()).
filter(query).build()).
build();
}
Expand Down
Loading
Loading