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 @@ -30,6 +30,7 @@
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.dao.search.AttrCond;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr;
Expand Down Expand Up @@ -64,6 +65,35 @@ public MaJPAJSONAnySearchDAO(
validator);
}

@Override
protected void parseOrderByForPlainSchema(
final SearchSupport svs,
final OrderBySupport obs,
final OrderBySupport.Item item,
final OrderByClause clause,
final PlainSchema schema,
final String fieldName) {

// keep track of involvement of non-mandatory schemas in the order by clauses
obs.nonMandatorySchemas = !"true".equals(schema.getMandatoryCondition());

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

item.select = new StringBuilder().
append("( SELECT usa").append('.').append(key(schema.getType())).
append(" FROM ").append(schema.isUniqueConstraint()
? svs.asSearchViewSupport().uniqueAttr().name
: svs.asSearchViewSupport().attr().name).
append(" usa WHERE usa.any_id = ").
append(defaultSV(svs).alias).
append(".any_id").
append(" AND usa.schema_id ='").append(fieldName).append("'").
append(" LIMIT 1").
append(") AS ").append(fieldName).toString();
item.where = "plainSchema = '" + fieldName + '\'';
item.orderBy = fieldName + ' ' + clause.getDirection().name();
}

@Override
protected AnySearchNode getQuery(
final AttrCond cond,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ protected void parseOrderByForPlainSchema(

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

item.select = new StringBuilder().append("( SELECT usa").
append('.').
append((schema.isUniqueConstraint() ? "attrUniqueValue" : key(schema.getType()))).
item.select = new StringBuilder().append(schema.isUniqueConstraint()
? "( SELECT JSON_UNQUOTE(JSON_EXTRACT(usa.attrUniqueValue, '$. " + key(schema.getType()) + "')) "
: "( SELECT usa." + key(schema.getType())).
append(" FROM ").
append(svs.field().name).
append(" usa WHERE usa.any_id = ").
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -995,9 +995,15 @@ protected void parseOrderByForPlainSchema(
obs.views.add(svs.asSearchViewSupport().uniqueAttr());

item.select = new StringBuilder().
append(svs.asSearchViewSupport().uniqueAttr().alias).append('.').
append(key(schema.getType())).
append(" AS ").append(fieldName).toString();
append("( SELECT usa").append('.').append(key(schema.getType())).
append(" FROM ").
append(svs.asSearchViewSupport().uniqueAttr().name).
append(" usa WHERE usa.any_id = ").
append(svs.asSearchViewSupport().uniqueAttr().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().uniqueAttr().alias).
append(".schema_id='").append(fieldName).append("'").toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,19 @@ public void issueSYNCOPE1906() {

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

// order by unique attribute
OrderByClause orderByFullname = new OrderByClause();
orderByFullname.setField("fullname");
orderByFullname.setDirection(OrderByClause.Direction.DESC);

users = searchDAO.search(SearchCond.getLeaf(idCond), List.of(orderByFullname), AnyTypeKind.USER);

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

private User addPlainAttr(final User user, final PlainSchema plainSchema, final String value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1573,20 +1573,13 @@ public void issueSYNCOPE1472() {

// 2. remove resources, auxiliary classes and roles
userUR.getResources().clear();
userUR.getResources().add(new StringPatchItem.Builder()
.value(RESOURCE_NAME_TESTDB)
.operation(PatchOperation.DELETE)
.build());
userUR.getResources().add(new StringPatchItem.Builder().value(RESOURCE_NAME_TESTDB)
.operation(PatchOperation.DELETE).build());
userUR.getAuxClasses().clear();
userUR.getAuxClasses().add(new StringPatchItem.Builder()
.value("csv")
.operation(PatchOperation.DELETE)
userUR.getAuxClasses().add(new StringPatchItem.Builder().value("csv").operation(PatchOperation.DELETE)
.build());
userUR.getRoles().clear();
userUR.getRoles().add(new StringPatchItem.Builder()
.value("Other")
.operation(PatchOperation.DELETE)
.build());
userUR.getRoles().add(new StringPatchItem.Builder().value("Other").operation(PatchOperation.DELETE).build());
updateUser(userUR);

UserTO userTO = USER_SERVICE.read("1417acbe-cbf6-4277-9372-e75e04f97000");
Expand All @@ -1603,8 +1596,7 @@ public void issueSYNCOPE1699() throws Exception {
req.setUsername(new StringReplacePatchItem.Builder().value("newUsername" + getUUIDString()).build());

WebClient webClient = WebClient.create(ADDRESS + "/users/" + userTO.getKey(), ADMIN_UNAME, ADMIN_PWD, null).
accept(MediaType.APPLICATION_JSON_TYPE).
type(MediaType.APPLICATION_JSON_TYPE);
accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE);

Response response = webClient.invoke(HttpMethod.PATCH, JSON_MAPPER.writeValueAsString(req));
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
Expand Down Expand Up @@ -1736,10 +1728,7 @@ void issueSYNCOPE1818() {

// 2. pull users from resource-db-pull
ExecTO execution = AbstractTaskITCase.execProvisioningTask(TASK_SERVICE,
TaskType.PULL,
"7c2242f4-14af-4ab5-af31-cdae23783655",
MAX_WAIT_SECONDS,
false);
TaskType.PULL, "7c2242f4-14af-4ab5-af31-cdae23783655", MAX_WAIT_SECONDS, false);
assertEquals("SUCCESS", execution.getStatus());
assertFalse(rossini.isSuspended());
assertEquals("active", rossini.getStatus());
Expand All @@ -1761,12 +1750,8 @@ void issueSYNCOPE1818() {
+ "'false' WHERE USERNAME = 'rossini'");

// 5. pull again rossini from resource-db-pull
execution = AbstractTaskITCase.execProvisioningTask(
TASK_SERVICE,
TaskType.PULL,
"7c2242f4-14af-4ab5-af31-cdae23783655",
MAX_WAIT_SECONDS,
false);
execution = AbstractTaskITCase.execProvisioningTask(TASK_SERVICE, TaskType.PULL,
"7c2242f4-14af-4ab5-af31-cdae23783655", MAX_WAIT_SECONDS, false);
assertEquals("SUCCESS", execution.getStatus());

rossini = USER_SERVICE.read("rossini");
Expand All @@ -1785,11 +1770,7 @@ void issueSYNCOPE1818() {

// 7. pull again rossini from resource-db-pull
execution = AbstractTaskITCase.execProvisioningTask(
TASK_SERVICE,
TaskType.PULL,
"7c2242f4-14af-4ab5-af31-cdae23783655",
MAX_WAIT_SECONDS,
false);
TASK_SERVICE, TaskType.PULL, "7c2242f4-14af-4ab5-af31-cdae23783655", MAX_WAIT_SECONDS, false);
assertEquals("SUCCESS", execution.getStatus());

rossini = USER_SERVICE.read("rossini");
Expand All @@ -1809,8 +1790,7 @@ void issueSYNCOPE1818() {
} finally {
// restore attributes and (if needed) status
updateUser(new UserUR.Builder(rossini.getKey()).
plainAttrs(
attrAddReplacePatch("surname", "Rossini"),
plainAttrs(attrAddReplacePatch("surname", "Rossini"),
new AttrPatch.Builder(
new Attr.Builder("email").build()).operation(PatchOperation.DELETE).build()).
resource(new StringPatchItem.Builder().
Expand Down Expand Up @@ -1846,34 +1826,28 @@ void issueSYNCOPE1853() {

// 3. propagation tasks cleanup
TASK_SERVICE.search(new TaskQuery.Builder(TaskType.PROPAGATION)
.anyTypeKind(AnyTypeKind.USER)
.resource(RESOURCE_NAME_LDAP)
.entityKey("c9b2dec2-00a7-4855-97c0-d854842b4b24")
.build()).getResult()
.anyTypeKind(AnyTypeKind.USER).resource(RESOURCE_NAME_LDAP)
.entityKey("c9b2dec2-00a7-4855-97c0-d854842b4b24").build()).getResult()
.forEach(pt -> TASK_SERVICE.delete(TaskType.PROPAGATION, pt.getKey()));
TASK_SERVICE.search(new TaskQuery.Builder(TaskType.PROPAGATION)
.anyTypeKind(AnyTypeKind.USER)
.resource(RESOURCE_NAME_LDAP)
.entityKey("b3cbc78d-32e6-4bd4-92e0-bbe07566a2ee")
.build()).getResult()
.anyTypeKind(AnyTypeKind.USER).resource(RESOURCE_NAME_LDAP)
.entityKey("b3cbc78d-32e6-4bd4-92e0-bbe07566a2ee").build()).getResult()
.forEach(pt -> TASK_SERVICE.delete(TaskType.PROPAGATION, pt.getKey()));

// 4. delete group cGroupForPropagation: no deprovision should be fired on bellini, since there is already
// bGroupForPropagation, deprovision instead must be fired for vivaldi
GROUP_SERVICE.delete(cGroupForPropagation.getKey());
await().during(5, TimeUnit.SECONDS).atMost(MAX_WAIT_SECONDS, TimeUnit.SECONDS).until(
() -> TASK_SERVICE.search(new TaskQuery.Builder(TaskType.PROPAGATION)
.anyTypeKind(AnyTypeKind.USER)
.resource(RESOURCE_NAME_LDAP)
.anyTypeKind(AnyTypeKind.USER).resource(RESOURCE_NAME_LDAP)
.entityKey("c9b2dec2-00a7-4855-97c0-d854842b4b24").build())
.getResult().stream().map(PropagationTaskTO.class::cast)
.collect(Collectors.toList()).stream().noneMatch(pt -> ResourceOperation.DELETE == pt.
getOperation()));
GROUP_SERVICE.delete(dGroupForPropagation.getKey());
await().atMost(MAX_WAIT_SECONDS, TimeUnit.SECONDS).until(
() -> TASK_SERVICE.search(new TaskQuery.Builder(TaskType.PROPAGATION)
.anyTypeKind(AnyTypeKind.USER)
.resource(RESOURCE_NAME_LDAP)
.anyTypeKind(AnyTypeKind.USER).resource(RESOURCE_NAME_LDAP)
.entityKey("b3cbc78d-32e6-4bd4-92e0-bbe07566a2ee").build())
.getResult().stream().map(PropagationTaskTO.class::cast)
.collect(Collectors.toList()).stream().anyMatch(pt -> ResourceOperation.DELETE == pt.
Expand All @@ -1886,7 +1860,7 @@ public void issueSYNCOPE1894() {
userWithDotSchema.setKey("user.testWithDot");
userWithDotSchema.setAnyTypeClass("minimal user");
SCHEMA_SERVICE.create(SchemaType.PLAIN, userWithDotSchema);

ResourceTO ldap = RESOURCE_SERVICE.read(RESOURCE_NAME_LDAP);
ldap.setKey("ldapWithDot");

Expand Down Expand Up @@ -1928,53 +1902,61 @@ public void issueSYNCOPE1894() {
@Test
public void issueSYNCOPE1906() {
UserCR userCR = UserITCase.getUniqueSample("issuesyncope1906@syncope.apache.org");
userCR.getPlainAttrs().removeIf(attr -> "ctype".equals(attr.getSchema()));
userCR.getPlainAttrs()
.removeIf(attr -> "ctype".equals(attr.getSchema()) || "fullname".equals(attr.getSchema()));
userCR.getPlainAttrs().add(attr("ctype", "aa1"));
userCR.getPlainAttrs().add(attr("fullname", "aa1"));
UserTO aa1 = createUser(userCR).getEntity();

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

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

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

userCR = UserITCase.getUniqueSample("issuesyncope1906@syncope.apache.org");
userCR.getPlainAttrs().removeIf(attr -> "ctype".equals(attr.getSchema()));
userCR.getPlainAttrs()
.removeIf(attr -> "ctype".equals(attr.getSchema()) || "fullname".equals(attr.getSchema()));
userCR.getPlainAttrs().add(attr("ctype", "aa5"));
userCR.getPlainAttrs().add(attr("fullname", "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 = UserITCase.getUniqueSample("actype@syncope.apache.org");
userCR.getPlainAttrs()
.removeIf(attr -> "ctype".equals(attr.getSchema()) || "fullname".equals(attr.getSchema()));
userCR.getPlainAttrs().add(attr("ctype", "a ctype"));
createUser(userCR).getEntity();
userCR.getPlainAttrs().add(attr("fullname", "a fullname"));
createUser(userCR);

userCR = UserITCase.getUniqueSample("issuesyncope1906@syncope.apache.org");
userCR.getPlainAttrs().removeIf(attr -> "ctype".equals(attr.getSchema()));
userCR = UserITCase.getUniqueSample("actypetwo@syncope.apache.org");
userCR.getPlainAttrs()
.removeIf(attr -> "ctype".equals(attr.getSchema()) || "fullname".equals(attr.getSchema()));
userCR.getPlainAttrs().add(attr("ctype", "a ctype 2"));
createUser(userCR).getEntity();
userCR.getPlainAttrs().add(attr("fullname", "a fullname 2"));
createUser(userCR);
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);
SyncopeClient.getUserSearchConditionBuilder().is("email").equalTo("*issuesyncope1906*")
.query()).size(0).page(1).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();
SyncopeClient.getUserSearchConditionBuilder().is("email").equalTo("*issuesyncope1906*")
.query()).size(10).page(1).orderBy("ctype DESC").build()).getResult();

assertEquals(5, users.size());

Expand All @@ -1983,13 +1965,32 @@ public void issueSYNCOPE1906() {
assertEquals(aa3.getUsername(), users.get(2).getUsername());
assertEquals(aa4.getUsername(), users.get(1).getUsername());
assertEquals(aa5.getUsername(), users.get(0).getUsername());

users = USER_SERVICE.search(new AnyQuery.Builder().fiql(
SyncopeClient.getUserSearchConditionBuilder().is("email").equalTo("*issuesyncope1906*")
.query()).size(10).page(1).orderBy("ctype ASC").build()).getResult();

assertEquals(aa5.getUsername(), users.get(4).getUsername());
assertEquals(aa4.getUsername(), users.get(3).getUsername());
assertEquals(aa3.getUsername(), users.get(2).getUsername());
assertEquals(aa2.getUsername(), users.get(1).getUsername());
assertEquals(aa1.getUsername(), users.get(0).getUsername());

// order by unique attribute
users = USER_SERVICE.search(new AnyQuery.Builder().fiql(
SyncopeClient.getUserSearchConditionBuilder().is("email").equalTo("*issuesyncope1906*")
.query()).size(10).page(1).orderBy("fullname ASC").build()).getResult();

assertEquals(aa5.getUsername(), users.get(4).getUsername());
assertEquals(aa4.getUsername(), users.get(3).getUsername());
assertEquals(aa3.getUsername(), users.get(2).getUsername());
assertEquals(aa2.getUsername(), users.get(1).getUsername());
assertEquals(aa1.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()));
.size(10).page(1).orderBy("ctype DESC").build()).getResult().forEach(u -> deleteUser(u.getKey()));
}
}
}
Loading