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 @@ -80,9 +80,17 @@ protected void parseOrderByForPlainSchema(

obs.views.add(svs.field());

item.select = svs.field().alias + '.'
+ (schema.isUniqueConstraint() ? "attrUniqueValue" : key(schema.getType()))
+ " AS " + fieldName;
item.select = new StringBuilder().append("( SELECT usa").
append('.').
append((schema.isUniqueConstraint() ? "attrUniqueValue" : key(schema.getType()))).
append(" FROM ").
append(svs.field().name).
append(" usa WHERE usa.any_id = ").
append(svs.field().alias).
append(".any_id").
append(" AND usa.plainSchema ='").append(fieldName).append("'").
append(" LIMIT 1").
append(") AS ").append(fieldName).toString();
item.where = "plainSchema = '" + fieldName + '\'';
item.orderBy = fieldName + ' ' + clause.getDirection().name();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,18 @@ protected void parseOrderByForPlainSchema(

obs.views.add(svs.field());

item.select = svs.field().alias + '.'
+ (schema.isUniqueConstraint() ? "u" : "") + key(schema.getType())
+ " AS " + fieldName;
item.select = new StringBuilder().append("( SELECT usa").
append('.').
append((schema.isUniqueConstraint() ? "u" : "") + key(schema.getType())).
append(" FROM ").
append(svs.field().name).
append(" usa WHERE usa.any_id = ").
append(svs.field().alias).
append(".any_id").
append(" AND usa.plainSchema ='").append(fieldName).append("'").
append(" FETCH FIRST 1 ROWS ONLY ").
append(") AS ").append(fieldName).toString();

item.where = "plainSchema = '" + fieldName + '\'';
item.orderBy = fieldName + ' ' + clause.getDirection().name();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1006,8 +1006,15 @@ protected void parseOrderByForPlainSchema(
obs.views.add(svs.asSearchViewSupport().attr());

item.select = new StringBuilder().
append(svs.asSearchViewSupport().attr().alias).append('.').append(key(schema.getType())).
append(" AS ").append(fieldName).toString();
append("( SELECT usa").append('.').append(key(schema.getType())).
append(" FROM ").
append(svs.asSearchViewSupport().attr().name).
append(" usa WHERE usa.any_id = ").
append(svs.asSearchViewSupport().attr().alias).
append(".any_id").
append(" AND usa.schema_id ='").append(fieldName).append("'").
append(isOracle() ? " FETCH FIRST 1 ROWS ONLY " : " LIMIT 1").
append(") AS ").append(fieldName).toString();
item.where = new StringBuilder().
append(svs.asSearchViewSupport().attr().alias).
append(".schema_id='").append(fieldName).append("'").toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.IdRepoEntitlement;
import org.apache.syncope.core.persistence.api.attrvalue.validation.PlainAttrValidationManager;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
import org.apache.syncope.core.persistence.api.dao.RoleDAO;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
Expand All @@ -56,6 +58,8 @@
import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.persistence.api.entity.PlainSchema;
import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership;
import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
import org.apache.syncope.core.persistence.api.entity.group.Group;
Expand Down Expand Up @@ -100,6 +104,15 @@ public class AnySearchTest extends AbstractTest {

@Autowired
private RoleDAO roleDAO;

@Autowired
private PlainSchemaDAO plainSchemaDAO;

@Autowired
private EntityFactory entityFactory;

@Autowired
private PlainAttrValidationManager validator;

@BeforeEach
public void adjustLoginDateForLocalSystem() throws ParseException {
Expand Down Expand Up @@ -973,4 +986,84 @@ public void issueSYNCOPE1419() {
assertNotNull(users);
assertEquals(4, users.size());
}

@Test
public void issueSYNCOPE1906() {
User bellini = userDAO.findByUsername("bellini");
assertNotNull(bellini);

PlainSchema ctypeSchema = plainSchemaDAO.find("ctype");
assertNotNull(ctypeSchema);

userDAO.save(addPlainAttr(bellini, ctypeSchema, "aa1"));

User puccini = userDAO.findByUsername("puccini");
assertNotNull(bellini);

userDAO.save(addPlainAttr(puccini, ctypeSchema, "aa2"));

User verdi = userDAO.findByUsername("verdi");
assertNotNull(verdi);

userDAO.save(addPlainAttr(verdi, ctypeSchema, "aa3"));

User vivaldi = userDAO.findByUsername("vivaldi");
assertNotNull(vivaldi);

userDAO.save(addPlainAttr(vivaldi, ctypeSchema, "aa4"));

User rossini = userDAO.findByUsername("rossini");
assertNotNull(rossini);

userDAO.save(addPlainAttr(rossini, ctypeSchema, "aa5"));

entityManager().flush();

OrderByClause orderByCtype = new OrderByClause();
orderByCtype.setField("ctype");
orderByCtype.setDirection(OrderByClause.Direction.DESC);

OrderByClause orderByFirstname = new OrderByClause();
orderByFirstname.setField("username");
orderByFirstname.setDirection(OrderByClause.Direction.DESC);

AnyCond idCond = new AnyCond(AttrCond.Type.ISNOTNULL);
idCond.setSchema("id");

List<User> users =
searchDAO.search(SearchCond.getLeaf(idCond), List.of(orderByCtype, orderByFirstname), AnyTypeKind.USER);

assertEquals("bellini", users.get(4).getUsername());
assertEquals("puccini", users.get(3).getUsername());
assertEquals("verdi", users.get(2).getUsername());
assertEquals("vivaldi", users.get(1).getUsername());
assertEquals("rossini", users.get(0).getUsername());

// order by ctype even not searching by it
AttrCond surnameCond = new AttrCond(AttrCond.Type.ILIKE);
surnameCond.setSchema("surname");
surnameCond.setExpression("%ini");

AttrCond coolCond = new AttrCond(AttrCond.Type.ISNULL);
coolCond.setSchema("cool");

users = searchDAO.search(SearchCond.getAnd(SearchCond.getLeaf(surnameCond), SearchCond.getLeaf(coolCond)),
List.of(orderByCtype), AnyTypeKind.USER);

assertFalse(users.isEmpty());
assertEquals(2, users.size());
}

private User addPlainAttr(final User user, final PlainSchema plainSchema, final String value) {
user.getPlainAttr(plainSchema.getKey())
.ifPresentOrElse(ctype -> ctype.getValues().get(0).setStringValue(value), () -> {
UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
attr.setOwner(user);
attr.setSchema(plainSchema);
attr.add(validator, value, anyUtilsFactory.getInstance(AnyTypeKind.USER));

user.add(attr);
});
return user;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
import org.apache.syncope.common.lib.types.TaskType;
import org.apache.syncope.common.lib.types.UnmatchingRule;
import org.apache.syncope.common.rest.api.RESTHeaders;
import org.apache.syncope.common.rest.api.beans.AnyQuery;
import org.apache.syncope.common.rest.api.beans.RealmQuery;
import org.apache.syncope.common.rest.api.beans.ReconQuery;
import org.apache.syncope.common.rest.api.beans.TaskQuery;
Expand Down Expand Up @@ -1923,4 +1924,72 @@ public void issueSYNCOPE1894() {
SCHEMA_SERVICE.delete(SchemaType.PLAIN, userWithDotSchema.getKey());
}
}

@Test
public void issueSYNCOPE1906() {
UserCR userCR = UserITCase.getUniqueSample("issuesyncope1906@syncope.apache.org");
userCR.getPlainAttrs().removeIf(attr -> "ctype".equals(attr.getSchema()));
userCR.getPlainAttrs().add(attr("ctype", "aa1"));
UserTO aa1 = createUser(userCR).getEntity();

userCR = UserITCase.getUniqueSample("issuesyncope1906@syncope.apache.org");
userCR.getPlainAttrs().removeIf(attr -> "ctype".equals(attr.getSchema()));
userCR.getPlainAttrs().add(attr("ctype", "aa2"));
UserTO aa2 = createUser(userCR).getEntity();

userCR = UserITCase.getUniqueSample("issuesyncope1906@syncope.apache.org");
userCR.getPlainAttrs().removeIf(attr -> "ctype".equals(attr.getSchema()));
userCR.getPlainAttrs().add(attr("ctype", "aa3"));
UserTO aa3 = createUser(userCR).getEntity();

userCR = UserITCase.getUniqueSample("issuesyncope1906@syncope.apache.org");
userCR.getPlainAttrs().removeIf(attr -> "ctype".equals(attr.getSchema()));
userCR.getPlainAttrs().add(attr("ctype", "aa4"));
UserTO aa4 = createUser(userCR).getEntity();

userCR = UserITCase.getUniqueSample("issuesyncope1906@syncope.apache.org");
userCR.getPlainAttrs().removeIf(attr -> "ctype".equals(attr.getSchema()));
userCR.getPlainAttrs().add(attr("ctype", "aa5"));
UserTO aa5 = createUser(userCR).getEntity();

// add also other users with valued ctype
userCR = UserITCase.getUniqueSample("issuesyncope1906@syncope.apache.org");
userCR.getPlainAttrs().removeIf(attr -> "ctype".equals(attr.getSchema()));
userCR.getPlainAttrs().add(attr("ctype", "a ctype"));
createUser(userCR).getEntity();

userCR = UserITCase.getUniqueSample("issuesyncope1906@syncope.apache.org");
userCR.getPlainAttrs().removeIf(attr -> "ctype".equals(attr.getSchema()));
userCR.getPlainAttrs().add(attr("ctype", "a ctype 2"));
createUser(userCR).getEntity();
try {
await().until(() -> USER_SERVICE.search(new AnyQuery.Builder().fiql(
SyncopeClient.getUserSearchConditionBuilder().is("ctype").equalTo("aa*").query())
.size(0)
.page(1)
.orderBy("ctype DESC")
.build()).getTotalCount() == 5);
List<UserTO> users = USER_SERVICE.search(new AnyQuery.Builder().fiql(
SyncopeClient.getUserSearchConditionBuilder().is("ctype").equalTo("aa*").query())
.size(10)
.page(1)
.orderBy("ctype DESC")
.build()).getResult();

assertEquals(5, users.size());

assertEquals(aa1.getUsername(), users.get(4).getUsername());
assertEquals(aa2.getUsername(), users.get(3).getUsername());
assertEquals(aa3.getUsername(), users.get(2).getUsername());
assertEquals(aa4.getUsername(), users.get(1).getUsername());
assertEquals(aa5.getUsername(), users.get(0).getUsername());
} finally {
USER_SERVICE.search(new AnyQuery.Builder().fiql(
SyncopeClient.getUserSearchConditionBuilder().is("ctype").equalTo("aa*").query())
.size(10)
.page(1)
.orderBy("ctype DESC")
.build()).getResult().forEach(u -> deleteUser(u.getKey()));
}
}
}