This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/master by this push:
new ffc76fcd0b [SYNCOPE-1894] adding support to attributes with dot on
resource mapping (#1139)
ffc76fcd0b is described below
commit ffc76fcd0bf698f746acfc4cc291c67afe6f5a50
Author: Andrea Patricelli <[email protected]>
AuthorDate: Thu Jul 17 16:45:39 2025 +0200
[SYNCOPE-1894] adding support to attributes with dot on resource mapping
(#1139)
---
.../core/provisioning/api/IntAttrNameParser.java | 21 ++++++----
.../provisioning/api/IntAttrNameParserTest.java | 11 +++++-
.../apache/syncope/fit/core/UserIssuesITCase.java | 46 ++++++++++++++++++++++
3 files changed, 69 insertions(+), 9 deletions(-)
diff --git
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/IntAttrNameParser.java
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/IntAttrNameParser.java
index 745525f2f0..7890936c61 100644
---
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/IntAttrNameParser.java
+++
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/IntAttrNameParser.java
@@ -22,6 +22,7 @@ import java.text.ParseException;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.apache.commons.lang3.Strings;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.SchemaType;
@@ -36,23 +37,26 @@ import
org.springframework.transaction.annotation.Transactional;
@SuppressWarnings({ "squid:S4784", "squid:S3776" })
public class IntAttrNameParser {
- protected static final String END_PATTERN = ")\\]\\.(.+)";
+ protected static final String END_PATTERN = "\\]\\.(.+)";
protected static final Pattern ENCLOSING_GROUP_PATTERN = Pattern.compile(
- "^groups\\[(" + Entity.ID_REGEX + END_PATTERN);
+ "^groups\\[(" + Entity.ID_REGEX + ")" + END_PATTERN);
protected static final Pattern RELATED_USER_PATTERN = Pattern.compile(
- "^users\\[(" + Entity.ID_REGEX + END_PATTERN);
+ "^users\\[(" + Entity.ID_REGEX + ")" + END_PATTERN);
protected static final Pattern RELATED_ANY_OBJECT_PATTERN =
Pattern.compile(
- "^anyObjects\\[(" + Entity.ID_REGEX + END_PATTERN);
+ "^anyObjects\\[(" + Entity.ID_REGEX + ")" + END_PATTERN);
protected static final Pattern MEMBERSHIP_PATTERN = Pattern.compile(
- "^memberships\\[(" + Entity.ID_REGEX + END_PATTERN);
+ "^memberships\\[(" + Entity.ID_REGEX + ")" + END_PATTERN);
protected static final Pattern RELATIONSHIP_PATTERN = Pattern.compile(
"^relationships\\[(" + Entity.ID_REGEX + ")\\]"
- + "\\[(" + Entity.ID_REGEX + END_PATTERN);
+ + "\\[(" + Entity.ID_REGEX + ")" + END_PATTERN);
+
+ protected static final CharSequence[] RESERVED_WORDS =
+ { "groups", "users", "anyObjects", "memberships", "relationships"
};
protected final PlainSchemaDAO plainSchemaDAO;
@@ -103,11 +107,12 @@ public class IntAttrNameParser {
public IntAttrName parse(final String intAttrName, final AnyTypeKind
provisionAnyTypeKind) throws ParseException {
IntAttrName result = new IntAttrName();
- if (intAttrName.indexOf('.') == -1) {
+ Matcher matcher = Pattern.compile(END_PATTERN).matcher(intAttrName);
+ if (!matcher.matches() && !Strings.CS.containsAny(intAttrName,
RESERVED_WORDS)) {
result.setAnyTypeKind(provisionAnyTypeKind);
setFieldOrSchemaName(intAttrName, result.getAnyTypeKind(), result);
} else {
- Matcher matcher = ENCLOSING_GROUP_PATTERN.matcher(intAttrName);
+ matcher = ENCLOSING_GROUP_PATTERN.matcher(intAttrName);
if (matcher.matches()) {
result.setAnyTypeKind(AnyTypeKind.GROUP);
result.setEnclosingGroup(matcher.group(1));
diff --git
a/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/IntAttrNameParserTest.java
b/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/IntAttrNameParserTest.java
index 5823218fb3..98412951d8 100644
---
a/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/IntAttrNameParserTest.java
+++
b/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/IntAttrNameParserTest.java
@@ -105,7 +105,7 @@ public class IntAttrNameParserTest extends AbstractTest {
lenient().when(plainSchemaDAO.findById(anyString())).thenAnswer(ic -> {
String schemaName = ic.getArgument(0);
switch (schemaName) {
- case "email", "firstname", "location", "index" -> {
+ case "email", "firstname", "location", "index",
"user.valueWithDot" -> {
PlainSchema schema = mock(PlainSchema.class);
lenient().when(schema.getKey()).thenReturn(schemaName);
lenient().when(schema.getType()).thenReturn(AttrSchemaType.String);
@@ -374,4 +374,13 @@ public class IntAttrNameParserTest extends AbstractTest {
assertNotNull(e);
}
}
+
+ @Test
+ public void issueSYNCOPE1894() throws ParseException {
+ IntAttrName intAttrName = intAttrNameParser.parse("user.valueWithDot",
AnyTypeKind.USER);
+ assertNotNull(intAttrName);
+ assertEquals(AnyTypeKind.USER, intAttrName.getAnyTypeKind());
+ assertNull(intAttrName.getField());
+ assertEquals("user.valueWithDot", intAttrName.getSchema().getKey());
+ }
}
diff --git
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java
index a005e94de1..e607048274 100644
---
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java
+++
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java
@@ -72,12 +72,14 @@ import org.apache.syncope.common.lib.to.MembershipTO;
import org.apache.syncope.common.lib.to.PlainSchemaTO;
import org.apache.syncope.common.lib.to.PropagationStatus;
import org.apache.syncope.common.lib.to.PropagationTaskTO;
+import org.apache.syncope.common.lib.to.Provision;
import org.apache.syncope.common.lib.to.ProvisioningResult;
import org.apache.syncope.common.lib.to.PushTaskTO;
import org.apache.syncope.common.lib.to.RealmTO;
import org.apache.syncope.common.lib.to.ReconStatus;
import org.apache.syncope.common.lib.to.ResourceTO;
import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.SchemaTO;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.AttrSchemaType;
@@ -1849,4 +1851,48 @@ public class UserIssuesITCase extends AbstractITCase {
.toList().stream().anyMatch(pt ->
ResourceOperation.DELETE == pt.
getOperation()));
}
+
+ @Test
+ public void issueSYNCOPE1894() {
+ SchemaTO userWithDotSchema = new PlainSchemaTO();
+ 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");
+
+ Provision provision =
ldap.getProvision(AnyTypeKind.USER.name()).orElseThrow();
+ provision.getMapping().getItems().removeIf(item ->
"mail".equals(item.getIntAttrName()));
+
+ ldap.getProvisions().clear();
+ ldap.getProvisions().add(provision);
+
+ Item item = new Item();
+ item.setIntAttrName(userWithDotSchema.getKey());
+ item.setExtAttrName("carLicense");
+ item.setPurpose(MappingPurpose.PROPAGATION);
+
+ provision.getMapping().add(item);
+
+ ldap = createResource(ldap);
+
+ try {
+ UserCR userCR =
UserITCase.getUniqueSample("[email protected]");
+ userCR.getPlainAttrs().add(attr("user.testWithDot",
"someCarLicenseValue"));
+ userCR.getResources().add(ldap.getKey());
+
+ ProvisioningResult<UserTO> result = createUser(userCR);
+ assertEquals(1, result.getPropagationStatuses().size());
+
assertNotNull(result.getPropagationStatuses().getFirst().getAfterObj());
+
+ Attr carLicense =
+
result.getPropagationStatuses().getFirst().getAfterObj().getAttr("carLicense").orElseThrow();
+ assertEquals(1, carLicense.getValues().size());
+ assertEquals("someCarLicenseValue",
carLicense.getValues().getFirst());
+ } finally {
+ RESOURCE_SERVICE.delete(ldap.getKey());
+ SCHEMA_SERVICE.delete(SchemaType.PLAIN,
userWithDotSchema.getKey());
+ }
+ }
}