This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch 4_0_X
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/4_0_X by this push:
new f4a5564151 Setting JexlPermissions
f4a5564151 is described below
commit f4a5564151bb252ae7f0dbe789cb8062345ec5ee
Author: Francesco Chicchiriccò <[email protected]>
AuthorDate: Fri Aug 21 18:07:22 2026 +0200
Setting JexlPermissions
---
.../core/persistence/api/entity/user/Account.java | 2 +-
.../core/provisioning/api/jexl/JexlFunctions.java | 1 +
.../core/provisioning/api/jexl/JexlTools.java | 41 ++++++++--
.../core/provisioning/api/AbstractTest.java | 3 +-
.../{JexlUtilsTest.java => JexlToolsTest.java} | 2 +-
.../provisioning/java/ProvisioningContext.java | 3 +-
.../core/provisioning/java/JexlToolsTest.java | 93 ++++++++++++++++++++++
.../DefaultNotificationManagerTest.java | 3 +-
8 files changed, 135 insertions(+), 13 deletions(-)
diff --git
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/Account.java
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/Account.java
index dc34148856..f6b2fc93b3 100644
---
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/Account.java
+++
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/Account.java
@@ -37,7 +37,7 @@ public interface Account {
void setPassword(String password);
void setCipherAlgorithm(CipherAlgorithm cipherAlgorithm);
-
+
Boolean isSuspended();
void setSuspended(Boolean suspended);
diff --git
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/jexl/JexlFunctions.java
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/jexl/JexlFunctions.java
index 56fd253091..72d18e859c 100644
---
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/jexl/JexlFunctions.java
+++
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/jexl/JexlFunctions.java
@@ -18,6 +18,7 @@
*/
package org.apache.syncope.core.provisioning.api.jexl;
+@FunctionalInterface
public interface JexlFunctions {
String getNamespace();
diff --git
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/jexl/JexlTools.java
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/jexl/JexlTools.java
index e34df5b5ba..333e886240 100644
---
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/jexl/JexlTools.java
+++
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/jexl/JexlTools.java
@@ -25,6 +25,7 @@ import org.apache.commons.jexl3.JexlEngine;
import org.apache.commons.jexl3.JexlException;
import org.apache.commons.jexl3.JexlExpression;
import org.apache.commons.jexl3.JxltEngine;
+import org.apache.commons.jexl3.introspection.JexlPermissions;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.core.persistence.api.entity.Attributable;
import org.apache.syncope.core.provisioning.api.DerAttrHandler;
@@ -39,6 +40,41 @@ public class JexlTools {
protected static final Logger LOG =
LoggerFactory.getLogger(JexlTools.class);
+ public static final JexlPermissions DEFAULT_PERMISSIONS =
JexlPermissions.RESTRICTED.compose(
+ "java.time.*",
+ "org.apache.syncope.* ",
+ "org.apache.syncope.core.persistence.jpa.entity.user { -JPAUser { "
+ + "getCipherAlgorithm(); "
+ + "getPassword(); "
+ + "getPasswordHistory(); "
+ + "getSecurityAnswer(); "
+ + "getMfa(); "
+ + "getToken(); "
+ + "getTokenExpireTime(); "
+ + "} }",
+ "org.apache.syncope.core.persistence.jpa.entity.user {
-JPALinkedAccount { "
+ + "getPassword(); "
+ + "} }",
+ "org.apache.syncope.core.persistence.neo4j.entity.user {
-Neo4jUser { "
+ + "getCipherAlgorithm(); "
+ + "getPassword(); "
+ + "getPasswordHistory(); "
+ + "getSecurityAnswer(); "
+ + "getMfa(); "
+ + "getToken(); "
+ + "getTokenExpireTime(); "
+ + "} }",
+ "org.apache.syncope.core.persistence.neo4j.entity.user {
-Neo4jLinkedAccount { "
+ + "getPassword(); "
+ + "} }",
+ "org.apache.syncope.common.lib.to { -UserTO { "
+ + "getPassword(); "
+ + "} }",
+ "org.apache.syncope.common.lib.to { -LinkedAccountTO { "
+ + "getPassword(); "
+ + "} }"
+ );
+
protected final JexlEngine jexlEngine;
protected final JxltEngine jxltEngine;
@@ -48,11 +84,6 @@ public class JexlTools {
this.jxltEngine = jexlEngine.createJxltEngine(false);
}
- public JexlTools(final JexlEngine jexlEngine, final JxltEngine jxltEngine)
{
- this.jexlEngine = jexlEngine;
- this.jxltEngine = jxltEngine;
- }
-
public boolean isExpressionValid(final String expression) {
boolean result;
try {
diff --git
a/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/AbstractTest.java
b/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/AbstractTest.java
index f923b6d3f0..f246b7c583 100644
---
a/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/AbstractTest.java
+++
b/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/AbstractTest.java
@@ -21,7 +21,6 @@ package org.apache.syncope.core.provisioning.api;
import java.util.Map;
import org.apache.commons.jexl3.JexlBuilder;
import org.apache.commons.jexl3.JexlEngine;
-import org.apache.commons.jexl3.introspection.JexlPermissions;
import org.apache.syncope.core.provisioning.api.jexl.EmptyClassLoader;
import org.apache.syncope.core.provisioning.api.jexl.JexlTools;
import org.apache.syncope.core.provisioning.api.jexl.SyncopeJexlFunctions;
@@ -40,7 +39,7 @@ public class AbstractTest {
protected JexlTools jexlTools() {
JexlEngine jexlEngine = new JexlBuilder().
loader(new EmptyClassLoader()).
- permissions(JexlPermissions.RESTRICTED.compose("java.time.*",
"org.apache.syncope.*")).
+ permissions(JexlTools.DEFAULT_PERMISSIONS).
namespaces(Map.of("syncope", new SyncopeJexlFunctions())).
cache(512).
silent(false).
diff --git
a/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/jexl/JexlUtilsTest.java
b/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/jexl/JexlToolsTest.java
similarity index 99%
rename from
core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/jexl/JexlUtilsTest.java
rename to
core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/jexl/JexlToolsTest.java
index 39cae5985f..f4bcbed020 100644
---
a/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/jexl/JexlUtilsTest.java
+++
b/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/jexl/JexlToolsTest.java
@@ -49,7 +49,7 @@ import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.springframework.test.util.ReflectionTestUtils;
-public class JexlUtilsTest extends AbstractTest {
+class JexlToolsTest extends AbstractTest {
@Mock
private JexlContext context;
diff --git
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java
index e07ea0e254..cef5714357 100644
---
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java
+++
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java
@@ -24,7 +24,6 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.commons.jexl3.JexlBuilder;
import org.apache.commons.jexl3.JexlEngine;
-import org.apache.commons.jexl3.introspection.JexlPermissions;
import org.apache.syncope.common.keymaster.client.api.ConfParamOps;
import org.apache.syncope.core.persistence.api.DomainHolder;
import org.apache.syncope.core.persistence.api.EncryptorManager;
@@ -199,7 +198,7 @@ public class ProvisioningContext {
public JexlTools jexlTools(final List<JexlFunctions> jexlFunctions) {
JexlEngine jexlEngine = new JexlBuilder().
loader(new EmptyClassLoader()).
- permissions(JexlPermissions.RESTRICTED.compose("java.time.*",
"org.apache.syncope.*")).
+ permissions(JexlTools.DEFAULT_PERMISSIONS).
namespaces(jexlFunctions.stream().
collect(Collectors.toMap(JexlFunctions::getNamespace,
Function.identity()))).
cache(512).
diff --git
a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/JexlToolsTest.java
b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/JexlToolsTest.java
new file mode 100644
index 0000000000..1b2540a57c
--- /dev/null
+++
b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/JexlToolsTest.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.Map;
+import org.apache.commons.jexl3.JexlContext;
+import org.apache.commons.jexl3.MapContext;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.user.UMembership;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.jexl.JexlContextBuilder;
+import org.apache.syncope.core.provisioning.api.jexl.JexlTools;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+class JexlToolsTest extends AbstractTest {
+
+ @Autowired
+ private EntityFactory entityFactory;
+
+ @Autowired
+ private JexlTools jexlTools;
+
+ @Test
+ void permissionFields() {
+ UserTO userTO = new UserTO();
+ userTO.setUsername("username1");
+ userTO.setPassword("userPassword1");
+
+ JexlContext ctx = new JexlContextBuilder().fields(userTO).build();
+
+ assertEquals("username1/", jexlTools.evaluateExpression("username +
'/' + password", ctx));
+ }
+
+ @Test
+ void permissionTemplate() {
+ UserTO userTO = new UserTO();
+ userTO.setUsername("username1");
+ userTO.setPassword("userPassword1");
+ userTO.getMemberships().add(new
MembershipTO.Builder("groupKey").groupName("groupName").build());
+
+ assertEquals(
+ "I am username1, my password is ''; my group is groupName",
+ jexlTools.evaluateTemplate(
+ "I am ${user.username}, my password is
'${user.password}'; "
+ + "my group is ${user.memberships[0].groupName}",
+ new MapContext(Map.of("user", userTO))));
+
+ User user = entityFactory.newEntity(User.class);
+ user.setUsername("username1");
+ user.setPassword("password1");
+
+ Group group = entityFactory.newEntity(Group.class);
+ group.setName("groupName");
+ UMembership membership = entityFactory.newEntity(UMembership.class);
+ membership.setLeftEnd(user);
+ membership.setRightEnd(group);
+ user.add(membership);
+
+ User manager = entityFactory.newEntity(User.class);
+ manager.setUsername("usernameM1");
+ manager.setPassword("passwordM1");
+
+ assertEquals(
+ "I am username1, my password is ''; "
+ + "my group is groupName",
+ jexlTools.evaluateTemplate(
+ "I am ${user.username}, my password is
'${user.password}'; "
+ + "my group is ${user.memberships[0].rightEnd.name}",
+ new MapContext(Map.of("user", user))));
+ }
+}
diff --git
a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManagerTest.java
b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManagerTest.java
index f85a7288dc..66a007ac90 100644
---
a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManagerTest.java
+++
b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManagerTest.java
@@ -35,7 +35,6 @@ import java.util.Optional;
import org.apache.commons.jexl3.JexlBuilder;
import org.apache.commons.jexl3.JexlEngine;
import org.apache.commons.jexl3.MapContext;
-import org.apache.commons.jexl3.introspection.JexlPermissions;
import org.apache.syncope.common.keymaster.client.api.ConfParamOps;
import org.apache.syncope.common.lib.Attr;
import org.apache.syncope.common.lib.SyncopeConstants;
@@ -136,7 +135,7 @@ public class DefaultNotificationManagerTest {
void init() {
JexlEngine jexlEngine = new JexlBuilder().
loader(new EmptyClassLoader()).
- permissions(JexlPermissions.RESTRICTED.compose("java.time.*",
"org.apache.syncope.*")).
+ permissions(JexlTools.DEFAULT_PERMISSIONS).
namespaces(Map.of("syncope", new SyncopeJexlFunctions())).
cache(512).
silent(false).