Skip to content

Commit 893db9c

Browse files
committed
[SYNCOPE-1957] Process auxClasses changes before attributes during update
1 parent ad68d03 commit 893db9c

7 files changed

Lines changed: 140 additions & 10 deletions

File tree

‎core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyDataBinder.java‎

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,25 @@ protected void processAttrPatch(
366366
}
367367
}
368368

369-
@SuppressWarnings({ "unchecked", "rawtypes" })
369+
protected void fillAuxClasses(final Relatable<?, ?> any, final AnyUR anyUR) {
370+
for (StringPatchItem patch : anyUR.getAuxClasses()) {
371+
anyTypeClassDAO.findById(patch.getValue()).ifPresentOrElse(
372+
auxClass -> {
373+
switch (patch.getOperation()) {
374+
case ADD_REPLACE:
375+
any.add(auxClass);
376+
break;
377+
378+
case DELETE:
379+
default:
380+
any.getAuxClasses().remove(auxClass);
381+
}
382+
},
383+
() -> LOG.debug("Invalid {} {}, ignoring...",
384+
AnyTypeClass.class.getSimpleName(), patch.getValue()));
385+
}
386+
}
387+
370388
protected void fill(
371389
final AnyTO anyTO,
372390
final Any any,

‎core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ public void create(final AnyObject anyObject, final AnyObjectCR anyObjectCR) {
245245

246246
@Override
247247
public PropagationByResource<String> update(final AnyObject toBeUpdated, final AnyObjectUR anyObjectUR) {
248+
fillAuxClasses(toBeUpdated, anyObjectUR);
249+
248250
// Re-merge any pending change from workflow tasks
249251
AnyObject anyObject = anyObjectDAO.save(toBeUpdated);
250252

‎core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ public void create(final Group group, final GroupCR groupCR) {
225225

226226
@Override
227227
public PropagationByResource<String> update(final Group toBeUpdated, final GroupUR groupUR) {
228+
fillAuxClasses(toBeUpdated, groupUR);
229+
228230
// Re-merge any pending change from workflow tasks
229231
Group group = groupDAO.save(toBeUpdated);
230232

‎core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,8 @@ protected boolean isPasswordMapped(final ExternalResource resource) {
370370

371371
@Override
372372
public UserWorkflowResult.PropagationInfo update(final User toBeUpdated, final UserUR userUR) {
373+
fillAuxClasses(toBeUpdated, userUR);
374+
373375
// Re-merge any pending change from workflow tasks
374376
User user = userDAO.save(toBeUpdated);
375377

‎ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/FlowableWorkflowContext.java‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ public Suspend suspend() {
248248

249249
@ConditionalOnMissingBean
250250
@Bean
251-
public Update update(final UserDataBinder userDataBinder, final UserDAO userDAO) {
252-
return new Update(userDataBinder, userDAO);
251+
public Update update(final UserDataBinder userDataBinder) {
252+
return new Update(userDataBinder);
253253
}
254254
}

‎ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/task/Update.java‎

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
import org.apache.syncope.common.lib.request.UserUR;
2222
import org.apache.syncope.core.flowable.impl.FlowableRuntimeUtils;
23-
import org.apache.syncope.core.persistence.api.dao.UserDAO;
2423
import org.apache.syncope.core.persistence.api.entity.user.User;
2524
import org.apache.syncope.core.provisioning.api.UserWorkflowResult;
2625
import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
@@ -30,11 +29,8 @@ public class Update extends FlowableServiceTask {
3029

3130
protected final UserDataBinder dataBinder;
3231

33-
protected final UserDAO userDAO;
34-
35-
public Update(final UserDataBinder dataBinder, final UserDAO userDAO) {
32+
public Update(final UserDataBinder dataBinder) {
3633
this.dataBinder = dataBinder;
37-
this.userDAO = userDAO;
3834
}
3935

4036
@Override
@@ -45,8 +41,6 @@ protected void doExecute(final DelegateExecution execution) {
4541
} else {
4642
User user = execution.getVariable(FlowableRuntimeUtils.USER, User.class);
4743

48-
user = userDAO.save(user);
49-
5044
UserWorkflowResult.PropagationInfo propInfo = dataBinder.update(user, req);
5145

5246
// report updated user and propagation by resource as result

‎fit/core-reference/src/test/java/org/apache/syncope/fit/core/AnyObjectITCase.java‎

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,40 @@
2626
import static org.junit.jupiter.api.Assertions.fail;
2727

2828
import jakarta.ws.rs.core.Response;
29+
import java.util.List;
2930
import java.util.Set;
3031
import java.util.UUID;
32+
import java.util.function.Consumer;
3133
import org.apache.syncope.client.lib.SyncopeClient;
3234
import org.apache.syncope.common.lib.Attr;
3335
import org.apache.syncope.common.lib.SyncopeClientException;
3436
import org.apache.syncope.common.lib.SyncopeConstants;
37+
import org.apache.syncope.common.lib.request.AnyCR;
3538
import org.apache.syncope.common.lib.request.AnyObjectCR;
3639
import org.apache.syncope.common.lib.request.AnyObjectUR;
40+
import org.apache.syncope.common.lib.request.AnyUR;
41+
import org.apache.syncope.common.lib.request.GroupCR;
42+
import org.apache.syncope.common.lib.request.GroupUR;
3743
import org.apache.syncope.common.lib.request.RelationshipUR;
3844
import org.apache.syncope.common.lib.request.StringPatchItem;
45+
import org.apache.syncope.common.lib.request.UserCR;
46+
import org.apache.syncope.common.lib.request.UserUR;
3947
import org.apache.syncope.common.lib.to.AnyObjectTO;
48+
import org.apache.syncope.common.lib.to.AnyTO;
49+
import org.apache.syncope.common.lib.to.AnyTypeClassTO;
4050
import org.apache.syncope.common.lib.to.ConnObject;
51+
import org.apache.syncope.common.lib.to.GroupTO;
4152
import org.apache.syncope.common.lib.to.PagedResult;
53+
import org.apache.syncope.common.lib.to.PlainSchemaTO;
4254
import org.apache.syncope.common.lib.to.RelationshipTO;
55+
import org.apache.syncope.common.lib.to.UserTO;
4356
import org.apache.syncope.common.lib.types.AnyTypeKind;
57+
import org.apache.syncope.common.lib.types.AttrSchemaType;
4458
import org.apache.syncope.common.lib.types.ClientExceptionType;
4559
import org.apache.syncope.common.lib.types.PatchOperation;
4660
import org.apache.syncope.common.lib.types.SchemaType;
4761
import org.apache.syncope.common.rest.api.beans.AnyQuery;
62+
import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
4863
import org.apache.syncope.fit.AbstractITCase;
4964
import org.junit.jupiter.api.Assertions;
5065
import org.junit.jupiter.api.Test;
@@ -327,4 +342,101 @@ public void issueSYNCOPE1686() {
327342
assertEquals(ClientExceptionType.InvalidRelationship, e.getType());
328343
assertTrue(e.getMessage().contains("Relationships shall be created or updated only from their left end"));
329344
}
345+
346+
public void issueSYNCOPE1957() {
347+
// prepare
348+
PlainSchemaTO schema1 = new PlainSchemaTO();
349+
schema1.setKey("schema1" + getUUIDString());
350+
schema1.setType(AttrSchemaType.Boolean);
351+
createSchema(SchemaType.PLAIN, schema1);
352+
353+
PlainSchemaTO schema2 = new PlainSchemaTO();
354+
schema2.setKey("schema2" + getUUIDString());
355+
schema2.setType(AttrSchemaType.Boolean);
356+
createSchema(SchemaType.PLAIN, schema2);
357+
358+
String class1Key = "class1" + getUUIDString();
359+
AnyTypeClassTO class1 = new AnyTypeClassTO();
360+
class1.setKey(class1Key);
361+
class1.getPlainSchemas().add(schema1.getKey());
362+
class1.getPlainSchemas().add(schema2.getKey());
363+
364+
Response response = ANY_TYPE_CLASS_SERVICE.create(class1);
365+
assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
366+
367+
class1 = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class);
368+
369+
// 1. create user, group and printer with auxClass class1
370+
Consumer<AnyCR> setupAnyCR = anyCR -> {
371+
anyCR.getResources().clear();
372+
anyCR.getAuxClasses().add(class1Key);
373+
anyCR.getPlainAttrs().add(attr(schema1.getKey(), "true"));
374+
anyCR.getPlainAttrs().add(attr(schema2.getKey(), "true"));
375+
};
376+
Consumer<AnyTO> checkAnyTO = anyTO -> {
377+
assertTrue(anyTO.getPlainAttr(schema1.getKey()).isPresent());
378+
assertTrue(anyTO.getPlainAttr(schema2.getKey()).isPresent());
379+
};
380+
381+
UserCR userCR = UserITCase.getUniqueSample("syncope1957@apache.org");
382+
setupAnyCR.accept(userCR);
383+
384+
UserTO user = createUser(userCR).getEntity();
385+
checkAnyTO.accept(user);
386+
387+
GroupCR groupCR = GroupITCase.getSample("syncope1957");
388+
setupAnyCR.accept(groupCR);
389+
390+
GroupTO group = createGroup(groupCR).getEntity();
391+
checkAnyTO.accept(group);
392+
393+
AnyObjectCR printerCR = getSample("syncope1957");
394+
setupAnyCR.accept(printerCR);
395+
396+
AnyObjectTO printer = createAnyObject(printerCR).getEntity();
397+
checkAnyTO.accept(printer);
398+
399+
// 2. create new anytypeclass and move schema there
400+
class1.getPlainSchemas().remove(schema2.getKey());
401+
ANY_TYPE_CLASS_SERVICE.update(class1);
402+
403+
class1 = ANY_TYPE_CLASS_SERVICE.read(class1.getKey());
404+
assertEquals(List.of(schema1.getKey()), class1.getPlainSchemas());
405+
406+
String class2Key = "class2" + getUUIDString();
407+
AnyTypeClassTO class2 = new AnyTypeClassTO();
408+
class2.setKey(class2Key);
409+
class2.getPlainSchemas().add(schema2.getKey());
410+
411+
response = ANY_TYPE_CLASS_SERVICE.create(class2);
412+
assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
413+
414+
class2 = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class);
415+
assertEquals(List.of(schema2.getKey()), class2.getPlainSchemas());
416+
417+
// 3. update user, group and printer by adding auxClass class2
418+
Consumer<AnyUR> setupAnyUR = anyUR -> anyUR.getAuxClasses().
419+
add(new StringPatchItem.Builder().value(class2Key).build());
420+
421+
UserUR userUR = new UserUR();
422+
userUR.setKey(user.getKey());
423+
setupAnyUR.accept(userUR);
424+
425+
user = updateUser(userUR).getEntity();
426+
checkAnyTO.accept(user);
427+
428+
GroupUR groupUR = new GroupUR();
429+
groupUR.setKey(group.getKey());
430+
setupAnyUR.accept(groupUR);
431+
432+
group = updateGroup(groupUR).getEntity();
433+
checkAnyTO.accept(group);
434+
435+
AnyObjectUR printerUR = new AnyObjectUR();
436+
printerUR.setKey(printer.getKey());
437+
setupAnyUR.accept(printerUR);
438+
439+
printer = updateAnyObject(printerUR).getEntity();
440+
checkAnyTO.accept(printer);
441+
}
330442
}

0 commit comments

Comments
 (0)