diff --git a/repository/src/main/java/org/alfresco/repo/action/ActionExecutionContext.java b/repository/src/main/java/org/alfresco/repo/action/ActionExecutionContext.java
new file mode 100644
index 0000000000..43f88b7037
--- /dev/null
+++ b/repository/src/main/java/org/alfresco/repo/action/ActionExecutionContext.java
@@ -0,0 +1,93 @@
+/*
+ * #%L
+ * Alfresco Repository
+ * %%
+ * Copyright (C) 2022 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.repo.action;
+
+import java.util.Objects;
+
+/**
+ * Instances of this class are responsible for holding an action id with additional data used to identify the action's
+ * execution context like:
+ *
+ * - REST API
+ * - rules execution
+ * - ...
+ *
+ */
+public class ActionExecutionContext
+{
+ private final String actionId;
+ private final String executionSource;
+
+ private ActionExecutionContext(String actionId, String executionSource)
+ {
+ this.actionId = actionId;
+ this.executionSource = executionSource;
+ }
+
+ String getActionId()
+ {
+ return actionId;
+ }
+
+ String getExecutionSource()
+ {
+ return executionSource;
+ }
+
+ boolean isExecutionSourceKnown()
+ {
+ return Objects.nonNull(executionSource);
+ }
+
+ public static Builder builder(final String actionId)
+ {
+ Objects.requireNonNull(actionId);
+ return new Builder(actionId);
+ }
+
+ public static class Builder
+ {
+ private final String actionId;
+ private String executionSource;
+
+ private Builder(String actionId)
+ {
+ this.actionId = actionId;
+ }
+
+ public ActionExecutionContext build()
+ {
+ return new ActionExecutionContext(actionId, executionSource);
+ }
+
+ public Builder withExecutionSource(final String executionSource)
+ {
+ Objects.requireNonNull(executionSource);
+ this.executionSource = executionSource;
+ return this;
+ }
+ }
+}
diff --git a/repository/src/main/java/org/alfresco/repo/action/ActionServiceImpl.java b/repository/src/main/java/org/alfresco/repo/action/ActionServiceImpl.java
index 23d0bfdcf2..ec9de682f9 100644
--- a/repository/src/main/java/org/alfresco/repo/action/ActionServiceImpl.java
+++ b/repository/src/main/java/org/alfresco/repo/action/ActionServiceImpl.java
@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
- * Copyright (C) 2005 - 2020 Alfresco Software Limited
+ * Copyright (C) 2005 - 2022 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -33,7 +33,14 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Properties;
import java.util.Set;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.evaluator.ActionConditionEvaluator;
@@ -120,6 +127,8 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
private ActionTrackingService actionTrackingService;
private PolicyComponent policyComponent;
private ActionServiceMonitor monitor;
+ private Properties configProperties;
+ private ActionExecutionValidator actionExecutionValidator;
/**
* The asynchronous action execution queues map of name, queue
@@ -236,7 +245,17 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
{
this.asynchronousActionExecutionQueues = asynchronousActionExecutionQueues;
}
-
+
+ public void setConfigurationProperties(Properties properties)
+ {
+ this.configProperties = properties;
+ }
+
+ protected Properties getConfigurationProperties()
+ {
+ return configProperties;
+ }
+
/**
* This method registers an {@link AsynchronousActionExecutionQueue} with the {@link ActionService}.
* @param key String
@@ -256,6 +275,11 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
ActionModel.TYPE_ACTION_PARAMETER, new JavaBehaviour(this, "getCopyCallback"));
this.policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onCopyComplete"),
ActionModel.TYPE_ACTION_PARAMETER, new JavaBehaviour(this, "onCopyComplete"));
+ if (configProperties == null)
+ {
+ configProperties = applicationContext.getBean("global-properties", Properties.class);
+ }
+ actionExecutionValidator = new ActionExecutionValidator(configProperties::getProperty, actionDefinitions::containsKey);
}
/**
@@ -1870,5 +1894,58 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
LoggingAwareExecuter executer = (LoggingAwareExecuter) this.applicationContext.getBean(action.getActionDefinitionName());
return executer.onLogException(logger,t, message);
}
-
+
+ @Override
+ public boolean isExposed(ActionExecutionContext actionExecutionContext)
+ {
+ return actionExecutionValidator.isExposed(actionExecutionContext);
+ }
+
+ static class ActionExecutionValidator
+ {
+ private final Function config;
+ private final Predicate isPublic;
+
+ ActionExecutionValidator(Function config, Predicate isPublic)
+ {
+ this.config = Objects.requireNonNull(config);
+ this.isPublic = Objects.requireNonNull(isPublic);
+ }
+
+ boolean isExposed(ActionExecutionContext actionExecutionContext)
+ {
+ Objects.requireNonNull(actionExecutionContext);
+ return isExposedInConfig(actionExecutionContext).orElseGet(() -> isPublic(actionExecutionContext));
+ }
+
+ private Optional isExposedInConfig(ActionExecutionContext actionExecutionContext)
+ {
+ return getConfigKeys(actionExecutionContext).
+ map(config).
+ filter(Objects::nonNull).
+ map(Boolean::parseBoolean).
+ findFirst();
+ }
+
+ private Boolean isPublic(ActionExecutionContext actionExecutionContext)
+ {
+ return isPublic.test(actionExecutionContext.getActionId());
+ }
+
+ private static Stream getConfigKeys(ActionExecutionContext actionExecutionContext)
+ {
+ if (actionExecutionContext.isExecutionSourceKnown())
+ {
+ return Stream.of(
+ getConfigKey(actionExecutionContext.getExecutionSource(), actionExecutionContext.getActionId()),
+ getConfigKey(actionExecutionContext.getActionId()));
+ }
+ return Stream.of(getConfigKey(actionExecutionContext.getActionId()));
+ }
+
+ static String getConfigKey(String... parts)
+ {
+ return Stream.of(parts).collect(Collectors.joining(".", "org.alfresco.repo.action.", ".exposed"));
+ }
+ }
}
diff --git a/repository/src/main/java/org/alfresco/repo/action/RuntimeActionService.java b/repository/src/main/java/org/alfresco/repo/action/RuntimeActionService.java
index d4c5f30de7..0b1b50035a 100644
--- a/repository/src/main/java/org/alfresco/repo/action/RuntimeActionService.java
+++ b/repository/src/main/java/org/alfresco/repo/action/RuntimeActionService.java
@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
- * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * Copyright (C) 2005 - 2022 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -125,4 +125,14 @@ public interface RuntimeActionService
* @return true if it was handled, false for default handling
*/
public boolean onLogException(Action action, Log logger, Throwable t, String message);
+
+ /**
+ * Allows you to check if an action can be executed/used in a given execution context
+ * @param actionExecutionContext describes action and its execution context
+ * @return true if action can be executed, false otherwise
+ */
+ default boolean isExposed(ActionExecutionContext actionExecutionContext)
+ {
+ return true;
+ }
}
diff --git a/repository/src/main/resources/alfresco/action-services-context.xml b/repository/src/main/resources/alfresco/action-services-context.xml
index 8c7f5258b4..3e55065a58 100644
--- a/repository/src/main/resources/alfresco/action-services-context.xml
+++ b/repository/src/main/resources/alfresco/action-services-context.xml
@@ -75,6 +75,9 @@
+
+
+
diff --git a/repository/src/test/java/org/alfresco/AllUnitTestsSuite.java b/repository/src/test/java/org/alfresco/AllUnitTestsSuite.java
index a956aeb879..d5006e9bd1 100644
--- a/repository/src/test/java/org/alfresco/AllUnitTestsSuite.java
+++ b/repository/src/test/java/org/alfresco/AllUnitTestsSuite.java
@@ -176,6 +176,7 @@ import org.junit.runners.Suite;
org.alfresco.repo.action.CompositeActionImplTest.class,
org.alfresco.repo.action.CompositeActionConditionImplTest.class,
org.alfresco.repo.action.executer.TransformActionExecuterTest.class,
+ org.alfresco.repo.action.PrivateActionValidationTest.class,
org.alfresco.repo.audit.AuditableAnnotationTest.class,
org.alfresco.repo.audit.PropertyAuditFilterTest.class,
org.alfresco.repo.audit.access.NodeChangeTest.class,
diff --git a/repository/src/test/java/org/alfresco/repo/action/ActionServiceImplTest.java b/repository/src/test/java/org/alfresco/repo/action/ActionServiceImplTest.java
index f227199b14..33d2df06e2 100644
--- a/repository/src/test/java/org/alfresco/repo/action/ActionServiceImplTest.java
+++ b/repository/src/test/java/org/alfresco/repo/action/ActionServiceImplTest.java
@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
- * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * Copyright (C) 2005 - 2022 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -25,28 +25,27 @@
*/
package org.alfresco.repo.action;
+import static org.alfresco.repo.action.ActionExecutionContext.builder;
+
import java.io.Serializable;
import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Properties;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator;
import org.alfresco.repo.action.evaluator.InCategoryEvaluator;
import org.alfresco.repo.action.evaluator.NoConditionEvaluator;
import org.alfresco.repo.action.evaluator.compare.ComparePropertyValueOperation;
-import org.alfresco.repo.action.executer.ActionExecuter;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.repo.action.executer.AddFeaturesActionExecuter;
import org.alfresco.repo.action.executer.CheckInActionExecuter;
import org.alfresco.repo.action.executer.CheckOutActionExecuter;
import org.alfresco.repo.action.executer.CompositeActionExecuter;
import org.alfresco.repo.action.executer.MoveActionExecuter;
-import org.alfresco.repo.action.executer.ScriptActionExecuter;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
@@ -65,19 +64,14 @@ import org.alfresco.service.cmr.action.CompositeActionCondition;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
import org.alfresco.service.cmr.repository.ContentData;
-import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.PermissionService;
-import org.alfresco.service.cmr.security.PersonService;
-import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.test_category.BaseSpringTestsCategory;
-import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.BaseAlfrescoSpringTest;
import org.alfresco.util.GUID;
-import org.alfresco.util.PropertyMap;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
@@ -103,13 +97,18 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
private NodeRef nodeRef;
private NodeRef folder;
private RetryingTransactionHelper transactionHelper;
+ private Properties globalConfig;
+ private RuntimeActionService runtimeActionService;
+
@Before
public void before() throws Exception
{
super.before();
- this.transactionHelper = (RetryingTransactionHelper)this.applicationContext.getBean("retryingTransactionHelper");
+ this.transactionHelper = applicationContext.getBean("retryingTransactionHelper", RetryingTransactionHelper.class);
+ this.globalConfig = applicationContext.getBean("global-properties", Properties.class);
+ this.runtimeActionService = this.applicationContext.getBean("actionService", RuntimeActionService.class);
// Create the node used for tests
this.nodeRef = this.nodeService.createNode(
@@ -1295,6 +1294,89 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
assertEquals(123455, action.getExecutionEndDate().getTime());
assertEquals(null, action.getExecutionFailureMessage());
}
+
+ @Test
+ public void testActionExposureBasedOnConfiguration()
+ {
+ globalConfig.remove("org.alfresco.repo.action.public-test-action.exposed");
+ globalConfig.remove("org.alfresco.repo.action.source.public-test-action.exposed");
+ globalConfig.remove("org.alfresco.repo.action.unknown.public-test-action.exposed");
+ assertTrue(runtimeActionService.isExposed(builder("public-test-action").build()));
+ assertTrue(runtimeActionService.isExposed(builder("public-test-action").withExecutionSource("source").build()));
+ assertTrue(runtimeActionService.isExposed(builder("public-test-action").withExecutionSource("unknown").build()));
+
+ globalConfig.setProperty("org.alfresco.repo.action.public-test-action.exposed", "true");
+ globalConfig.remove("org.alfresco.repo.action.source.public-test-action.exposed");
+ globalConfig.remove("org.alfresco.repo.action.unknown.public-test-action.exposed");
+ assertTrue(runtimeActionService.isExposed(builder("public-test-action").build()));
+ assertTrue(runtimeActionService.isExposed(builder("public-test-action").withExecutionSource("source").build()));
+ assertTrue(runtimeActionService.isExposed(builder("public-test-action").withExecutionSource("unknown").build()));
+
+ globalConfig.setProperty("org.alfresco.repo.action.public-test-action.exposed", "false");
+ globalConfig.remove("org.alfresco.repo.action.source.public-test-action.exposed");
+ globalConfig.remove("org.alfresco.repo.action.unknown.public-test-action.exposed");
+ assertFalse(runtimeActionService.isExposed(builder("public-test-action").build()));
+ assertFalse(runtimeActionService.isExposed(builder("public-test-action").withExecutionSource("source").build()));
+ assertFalse(runtimeActionService.isExposed(builder("public-test-action").withExecutionSource("unknown").build()));
+
+ globalConfig.remove("org.alfresco.repo.action.public-test-action.exposed");
+ globalConfig.setProperty("org.alfresco.repo.action.source.public-test-action.exposed", "true");
+ globalConfig.remove("org.alfresco.repo.action.unknown.public-test-action.exposed");
+ assertTrue(runtimeActionService.isExposed(builder("public-test-action").build()));
+ assertTrue(runtimeActionService.isExposed(builder("public-test-action").withExecutionSource("source").build()));
+ assertTrue(runtimeActionService.isExposed(builder("public-test-action").withExecutionSource("unknown").build()));
+
+ globalConfig.remove("org.alfresco.repo.action.public-test-action.exposed");
+ globalConfig.setProperty("org.alfresco.repo.action.source.public-test-action.exposed", "false");
+ globalConfig.remove("org.alfresco.repo.action.unknown.public-test-action.exposed");
+ assertTrue(runtimeActionService.isExposed(builder("public-test-action").build()));
+ assertFalse(runtimeActionService.isExposed(builder("public-test-action").withExecutionSource("source").build()));
+ assertTrue(runtimeActionService.isExposed(builder("public-test-action").withExecutionSource("unknown").build()));
+
+ globalConfig.remove("org.alfresco.repo.action.private-test-action.exposed");
+ globalConfig.remove("org.alfresco.repo.action.source.private-test-action.exposed");
+ globalConfig.remove("org.alfresco.repo.action.unknown.private-test-action.exposed");
+ assertFalse(runtimeActionService.isExposed(builder("private-test-action").build()));
+ assertFalse(runtimeActionService.isExposed(builder("private-test-action").withExecutionSource("source").build()));
+ assertFalse(runtimeActionService.isExposed(builder("private-test-action").withExecutionSource("unknown").build()));
+
+ globalConfig.setProperty("org.alfresco.repo.action.private-test-action.exposed", "true");
+ globalConfig.remove("org.alfresco.repo.action.source.private-test-action.exposed");
+ globalConfig.remove("org.alfresco.repo.action.unknown.private-test-action.exposed");
+ assertTrue(runtimeActionService.isExposed(builder("private-test-action").build()));
+ assertTrue(runtimeActionService.isExposed(builder("private-test-action").withExecutionSource("source").build()));
+ assertTrue(runtimeActionService.isExposed(builder("private-test-action").withExecutionSource("unknown").build()));
+
+ globalConfig.setProperty("org.alfresco.repo.action.private-test-action.exposed", "false");
+ globalConfig.remove("org.alfresco.repo.action.source.private-test-action.exposed");
+ globalConfig.remove("org.alfresco.repo.action.unknown.private-test-action.exposed");
+ assertFalse(runtimeActionService.isExposed(builder("private-test-action").build()));
+ assertFalse(runtimeActionService.isExposed(builder("private-test-action").withExecutionSource("source").build()));
+ assertFalse(runtimeActionService.isExposed(builder("private-test-action").withExecutionSource("unknown").build()));
+
+ globalConfig.remove("org.alfresco.repo.action.private-test-action.exposed");
+ globalConfig.setProperty("org.alfresco.repo.action.source.private-test-action.exposed", "true");
+ globalConfig.remove("org.alfresco.repo.action.unknown.private-test-action.exposed");
+ assertFalse(runtimeActionService.isExposed(builder("private-test-action").build()));
+ assertTrue(runtimeActionService.isExposed(builder("private-test-action").withExecutionSource("source").build()));
+ assertFalse(runtimeActionService.isExposed(builder("private-test-action").withExecutionSource("unknown").build()));
+
+ globalConfig.remove("org.alfresco.repo.action.private-test-action.exposed");
+ globalConfig.setProperty("org.alfresco.repo.action.source.private-test-action.exposed", "false");
+ globalConfig.remove("org.alfresco.repo.action.unknown.private-test-action.exposed");
+ assertFalse(runtimeActionService.isExposed(builder("private-test-action").build()));
+ assertFalse(runtimeActionService.isExposed(builder("private-test-action").withExecutionSource("source").build()));
+ assertFalse(runtimeActionService.isExposed(builder("private-test-action").withExecutionSource("unknown").build()));
+ }
+
+ @Test
+ public void testIfGlobalConfigurationIsUsedEvenIfNotInjectedBySpring()
+ {
+ TestExtendedActionServiceImpl extended = applicationContext.getBean("extendedActionServiceWithoutConfigurationProperty", TestExtendedActionServiceImpl.class);
+
+ assertNotNull(extended.getConfigurationProperties());
+ assertSame(globalConfig, extended.getConfigurationProperties());
+ }
/**
* This method returns an {@link Action} which will fail when executed.
@@ -1509,8 +1591,26 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
throw new ActionServiceTransientException("action failed intentionally in " + TransientFailActionExecuter.class.getSimpleName());
}
}
-
+ public static class NoOpActionExecuter extends ActionExecuterAbstractBase
+ {
+ @Override
+ protected void addParameterDefinitions(List paramList)
+ {
+ //do nothing
+ }
+
+ @Override
+ protected void executeImpl(Action action, NodeRef actionedUponNodeRef)
+ {
+ //do nothing
+ }
+ }
+
+ public static class TestExtendedActionServiceImpl extends ActionServiceImpl
+ {
+
+ }
protected static class CancellableSleepAction extends ActionImpl implements CancellableAction
{
diff --git a/repository/src/test/java/org/alfresco/repo/action/PrivateActionValidationTest.java b/repository/src/test/java/org/alfresco/repo/action/PrivateActionValidationTest.java
new file mode 100644
index 0000000000..3f4f98b7c6
--- /dev/null
+++ b/repository/src/test/java/org/alfresco/repo/action/PrivateActionValidationTest.java
@@ -0,0 +1,152 @@
+/*
+ * #%L
+ * Alfresco Repository
+ * %%
+ * Copyright (C) 2005 - 2022 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.repo.action;
+
+import static org.alfresco.repo.action.ActionExecutionContext.builder;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.alfresco.repo.action.ActionServiceImpl.ActionExecutionValidator;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class PrivateActionValidationTest
+{
+ @Test
+ public void shouldFailOnNullContext()
+ {
+ final ActionExecutionValidator validator = givenActionExecutionValidator(Map.of(), Set.of());
+
+ try
+ {
+ validator.isExposed(null);
+ }
+ catch (NullPointerException e)
+ {
+ assertNotNull(e);
+ return;
+ }
+ fail("Expected NPE.");
+ }
+
+ @Test
+ public void privateActionShouldNotBeExposedByDefault()
+ {
+ final ActionExecutionValidator validator = givenActionExecutionValidator(Map.of(), Set.of());
+
+ Assert.assertFalse(validator.isExposed(builder("privateA").build()));
+ Assert.assertFalse(validator.isExposed(builder("privateA").withExecutionSource("test").build()));
+ }
+
+ @Test
+ public void publicActionShouldBeExposedByDefault()
+ {
+ final ActionExecutionValidator validator = givenActionExecutionValidator(Map.of(), Set.of("publicA"));
+
+ Assert.assertTrue(validator.isExposed(builder("publicA").build()));
+ Assert.assertTrue(validator.isExposed(builder("publicA").withExecutionSource("test").build()));
+ }
+
+ @Test
+ public void privateActionShouldBeExposedByConfigurationBasedOnActionId()
+ {
+ final ActionExecutionValidator validator = givenActionExecutionValidator(Map.of(
+ "org.alfresco.repo.action.privateA.exposed", "true"), Set.of());
+
+ Assert.assertTrue(validator.isExposed(builder("privateA").build()));
+ Assert.assertTrue(validator.isExposed(builder("privateA").withExecutionSource("test").build()));
+ Assert.assertTrue(validator.isExposed(builder("privateA").withExecutionSource("test2").build()));
+
+ Assert.assertFalse(validator.isExposed(builder("privateB").build()));
+ Assert.assertFalse(validator.isExposed(builder("privateB").withExecutionSource("test").build()));
+ Assert.assertFalse(validator.isExposed(builder("privateB").withExecutionSource("test2").build()));
+ }
+
+ @Test
+ public void privateActionShouldBeExposedByConfigurationBasedOnActionIdAndExecutionSource()
+ {
+ final ActionExecutionValidator validator = givenActionExecutionValidator(Map.of(
+ "org.alfresco.repo.action.test.privateA.exposed", "true"), Set.of());
+
+ Assert.assertFalse(validator.isExposed(builder("privateA").build()));
+ Assert.assertTrue(validator.isExposed(builder("privateA").withExecutionSource("test").build()));
+ Assert.assertFalse(validator.isExposed(builder("privateA").withExecutionSource("test2").build()));
+
+ Assert.assertFalse(validator.isExposed(builder("privateB").build()));
+ Assert.assertFalse(validator.isExposed(builder("privateB").withExecutionSource("test").build()));
+ Assert.assertFalse(validator.isExposed(builder("privateB").withExecutionSource("test2").build()));
+ }
+
+ @Test
+ public void executionSourceConfigurationShouldTakePrecedenceOverGeneralConfigurationForPrivateAction()
+ {
+ final ActionExecutionValidator validator = givenActionExecutionValidator(Map.of(
+ "org.alfresco.repo.action.test.privateA.exposed", "true",
+ "org.alfresco.repo.action.privateA.exposed", "false"), Set.of());
+
+ Assert.assertFalse(validator.isExposed(builder("privateA").build()));
+ Assert.assertTrue(validator.isExposed(builder("privateA").withExecutionSource("test").build()));
+ }
+
+ @Test
+ public void publicActionShouldNotBeExposedByConfigurationBasedOnActionId()
+ {
+ final ActionExecutionValidator validator = givenActionExecutionValidator(Map.of(
+ "org.alfresco.repo.action.publicA.exposed", "false"), Set.of("publicA"));
+
+ Assert.assertFalse(validator.isExposed(builder("publicA").build()));
+ Assert.assertFalse(validator.isExposed(builder("publicA").withExecutionSource("test").build()));
+ }
+
+ @Test
+ public void publicActionShouldNotBeExposedByConfigurationBasedOnActionIdAndExecutionSource()
+ {
+ final ActionExecutionValidator validator = givenActionExecutionValidator(Map.of(
+ "org.alfresco.repo.action.test.publicA.exposed", "false"), Set.of("publicA"));
+
+ Assert.assertTrue(validator.isExposed(builder("publicA").build()));
+ Assert.assertFalse(validator.isExposed(builder("publicA").withExecutionSource("test").build()));
+ }
+
+ @Test
+ public void executionSourceConfigurationShouldTakePrecedenceOverGeneralConfigurationForPublicAction()
+ {
+ final ActionExecutionValidator validator = givenActionExecutionValidator(Map.of(
+ "org.alfresco.repo.action.test.publicA.exposed", "false",
+ "org.alfresco.repo.action.publicA.exposed", "true"), Set.of("publicA"));
+
+ Assert.assertTrue(validator.isExposed(builder("publicA").build()));
+ Assert.assertFalse(validator.isExposed(builder("publicA").withExecutionSource("test").build()));
+ }
+
+ private ActionExecutionValidator givenActionExecutionValidator(Map configuration, Set publicActions)
+ {
+ return new ActionExecutionValidator(configuration::get, publicActions::contains);
+ }
+}
diff --git a/repository/src/test/resources/org/alfresco/repo/action/test-action-services-context.xml b/repository/src/test/resources/org/alfresco/repo/action/test-action-services-context.xml
index 93586a134b..6ba0bbf43d 100644
--- a/repository/src/test/resources/org/alfresco/repo/action/test-action-services-context.xml
+++ b/repository/src/test/resources/org/alfresco/repo/action/test-action-services-context.xml
@@ -11,6 +11,18 @@
1000
+
+
+
+ true
+
+
+
+
+
+ false
+
+
@@ -31,4 +43,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+