mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
ACS-2744 Private action validation logic (#1051)
This commit is contained in:
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
* #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:
|
||||||
|
* <ul>
|
||||||
|
* <li>REST API</li>
|
||||||
|
* <li>rules execution</li>
|
||||||
|
* <li>...</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* 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.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
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.model.ContentModel;
|
||||||
import org.alfresco.repo.action.evaluator.ActionConditionEvaluator;
|
import org.alfresco.repo.action.evaluator.ActionConditionEvaluator;
|
||||||
@@ -120,6 +127,8 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
|
|||||||
private ActionTrackingService actionTrackingService;
|
private ActionTrackingService actionTrackingService;
|
||||||
private PolicyComponent policyComponent;
|
private PolicyComponent policyComponent;
|
||||||
private ActionServiceMonitor monitor;
|
private ActionServiceMonitor monitor;
|
||||||
|
private Properties configProperties;
|
||||||
|
private ActionExecutionValidator actionExecutionValidator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The asynchronous action execution queues map of name, queue
|
* The asynchronous action execution queues map of name, queue
|
||||||
@@ -236,7 +245,17 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
|
|||||||
{
|
{
|
||||||
this.asynchronousActionExecutionQueues = asynchronousActionExecutionQueues;
|
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}.
|
* This method registers an {@link AsynchronousActionExecutionQueue} with the {@link ActionService}.
|
||||||
* @param key String
|
* @param key String
|
||||||
@@ -256,6 +275,11 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
|
|||||||
ActionModel.TYPE_ACTION_PARAMETER, new JavaBehaviour(this, "getCopyCallback"));
|
ActionModel.TYPE_ACTION_PARAMETER, new JavaBehaviour(this, "getCopyCallback"));
|
||||||
this.policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onCopyComplete"),
|
this.policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onCopyComplete"),
|
||||||
ActionModel.TYPE_ACTION_PARAMETER, new JavaBehaviour(this, "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());
|
LoggingAwareExecuter executer = (LoggingAwareExecuter) this.applicationContext.getBean(action.getActionDefinitionName());
|
||||||
return executer.onLogException(logger,t, message);
|
return executer.onLogException(logger,t, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isExposed(ActionExecutionContext actionExecutionContext)
|
||||||
|
{
|
||||||
|
return actionExecutionValidator.isExposed(actionExecutionContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ActionExecutionValidator
|
||||||
|
{
|
||||||
|
private final Function<String, String> config;
|
||||||
|
private final Predicate<String> isPublic;
|
||||||
|
|
||||||
|
ActionExecutionValidator(Function<String, String> config, Predicate<String> 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<Boolean> 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<String> 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"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* 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
|
* @return true if it was handled, false for default handling
|
||||||
*/
|
*/
|
||||||
public boolean onLogException(Action action, Log logger, Throwable t, String message);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -75,6 +75,9 @@
|
|||||||
<property name="monitor">
|
<property name="monitor">
|
||||||
<ref bean="actionServiceMonitor"/>
|
<ref bean="actionServiceMonitor"/>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="configurationProperties">
|
||||||
|
<ref bean="global-properties"/>
|
||||||
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="defaultAsynchronousActionExecutionQueue" class="org.alfresco.repo.action.AsynchronousActionExecutionQueueImpl" init-method="init">
|
<bean id="defaultAsynchronousActionExecutionQueue" class="org.alfresco.repo.action.AsynchronousActionExecutionQueueImpl" init-method="init">
|
||||||
|
@@ -176,6 +176,7 @@ import org.junit.runners.Suite;
|
|||||||
org.alfresco.repo.action.CompositeActionImplTest.class,
|
org.alfresco.repo.action.CompositeActionImplTest.class,
|
||||||
org.alfresco.repo.action.CompositeActionConditionImplTest.class,
|
org.alfresco.repo.action.CompositeActionConditionImplTest.class,
|
||||||
org.alfresco.repo.action.executer.TransformActionExecuterTest.class,
|
org.alfresco.repo.action.executer.TransformActionExecuterTest.class,
|
||||||
|
org.alfresco.repo.action.PrivateActionValidationTest.class,
|
||||||
org.alfresco.repo.audit.AuditableAnnotationTest.class,
|
org.alfresco.repo.audit.AuditableAnnotationTest.class,
|
||||||
org.alfresco.repo.audit.PropertyAuditFilterTest.class,
|
org.alfresco.repo.audit.PropertyAuditFilterTest.class,
|
||||||
org.alfresco.repo.audit.access.NodeChangeTest.class,
|
org.alfresco.repo.audit.access.NodeChangeTest.class,
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -25,28 +25,27 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.action;
|
package org.alfresco.repo.action;
|
||||||
|
|
||||||
|
import static org.alfresco.repo.action.ActionExecutionContext.builder;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator;
|
import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator;
|
||||||
import org.alfresco.repo.action.evaluator.InCategoryEvaluator;
|
import org.alfresco.repo.action.evaluator.InCategoryEvaluator;
|
||||||
import org.alfresco.repo.action.evaluator.NoConditionEvaluator;
|
import org.alfresco.repo.action.evaluator.NoConditionEvaluator;
|
||||||
import org.alfresco.repo.action.evaluator.compare.ComparePropertyValueOperation;
|
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.ActionExecuterAbstractBase;
|
||||||
import org.alfresco.repo.action.executer.AddFeaturesActionExecuter;
|
import org.alfresco.repo.action.executer.AddFeaturesActionExecuter;
|
||||||
import org.alfresco.repo.action.executer.CheckInActionExecuter;
|
import org.alfresco.repo.action.executer.CheckInActionExecuter;
|
||||||
import org.alfresco.repo.action.executer.CheckOutActionExecuter;
|
import org.alfresco.repo.action.executer.CheckOutActionExecuter;
|
||||||
import org.alfresco.repo.action.executer.CompositeActionExecuter;
|
import org.alfresco.repo.action.executer.CompositeActionExecuter;
|
||||||
import org.alfresco.repo.action.executer.MoveActionExecuter;
|
import org.alfresco.repo.action.executer.MoveActionExecuter;
|
||||||
import org.alfresco.repo.action.executer.ScriptActionExecuter;
|
|
||||||
import org.alfresco.repo.content.MimetypeMap;
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
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.action.ParameterDefinition;
|
||||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||||
import org.alfresco.service.cmr.repository.ContentData;
|
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.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.cmr.security.PermissionService;
|
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.namespace.QName;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.alfresco.test_category.BaseSpringTestsCategory;
|
import org.alfresco.test_category.BaseSpringTestsCategory;
|
||||||
import org.alfresco.util.ApplicationContextHelper;
|
|
||||||
import org.alfresco.util.BaseAlfrescoSpringTest;
|
import org.alfresco.util.BaseAlfrescoSpringTest;
|
||||||
import org.alfresco.util.GUID;
|
import org.alfresco.util.GUID;
|
||||||
import org.alfresco.util.PropertyMap;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.experimental.categories.Category;
|
import org.junit.experimental.categories.Category;
|
||||||
@@ -103,13 +97,18 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
private NodeRef nodeRef;
|
private NodeRef nodeRef;
|
||||||
private NodeRef folder;
|
private NodeRef folder;
|
||||||
private RetryingTransactionHelper transactionHelper;
|
private RetryingTransactionHelper transactionHelper;
|
||||||
|
private Properties globalConfig;
|
||||||
|
private RuntimeActionService runtimeActionService;
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before() throws Exception
|
public void before() throws Exception
|
||||||
{
|
{
|
||||||
super.before();
|
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
|
// Create the node used for tests
|
||||||
this.nodeRef = this.nodeService.createNode(
|
this.nodeRef = this.nodeService.createNode(
|
||||||
@@ -1295,6 +1294,89 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
assertEquals(123455, action.getExecutionEndDate().getTime());
|
assertEquals(123455, action.getExecutionEndDate().getTime());
|
||||||
assertEquals(null, action.getExecutionFailureMessage());
|
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.
|
* 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());
|
throw new ActionServiceTransientException("action failed intentionally in " + TransientFailActionExecuter.class.getSimpleName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class NoOpActionExecuter extends ActionExecuterAbstractBase
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected void addParameterDefinitions(List<ParameterDefinition> 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
|
protected static class CancellableSleepAction extends ActionImpl implements CancellableAction
|
||||||
{
|
{
|
||||||
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
* #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<String, String> configuration, Set<String> publicActions)
|
||||||
|
{
|
||||||
|
return new ActionExecutionValidator(configuration::get, publicActions::contains);
|
||||||
|
}
|
||||||
|
}
|
@@ -11,6 +11,18 @@
|
|||||||
<value>1000</value>
|
<value>1000</value>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="public-test-action" class="org.alfresco.repo.action.ActionServiceImplTest$NoOpActionExecuter" parent="action-executer">
|
||||||
|
<property name="publicAction">
|
||||||
|
<value>true</value>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="private-test-action" class="org.alfresco.repo.action.ActionServiceImplTest$NoOpActionExecuter" parent="action-executer">
|
||||||
|
<property name="publicAction">
|
||||||
|
<value>false</value>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean id="sleepActionFilter" class="org.alfresco.repo.action.ActionServiceImplTest$SleepActionFilter" parent="baseActionFilter">
|
<bean id="sleepActionFilter" class="org.alfresco.repo.action.ActionServiceImplTest$SleepActionFilter" parent="baseActionFilter">
|
||||||
<property name="name">
|
<property name="name">
|
||||||
@@ -31,4 +43,28 @@
|
|||||||
<bean id="transient-fail-action"
|
<bean id="transient-fail-action"
|
||||||
class="org.alfresco.repo.action.ActionServiceImplTest$TransientFailActionExecuter"
|
class="org.alfresco.repo.action.ActionServiceImplTest$TransientFailActionExecuter"
|
||||||
parent="action-executer" />
|
parent="action-executer" />
|
||||||
|
|
||||||
|
<bean id="extendedActionServiceWithoutConfigurationProperty" class="org.alfresco.repo.action.ActionServiceImplTest$TestExtendedActionServiceImpl" init-method="init">
|
||||||
|
<property name="policyComponent">
|
||||||
|
<ref bean="policyComponent" />
|
||||||
|
</property>
|
||||||
|
<property name="nodeService">
|
||||||
|
<ref bean="NodeService" />
|
||||||
|
</property>
|
||||||
|
<property name="searchService">
|
||||||
|
<ref bean="ADMSearchService" />
|
||||||
|
</property>
|
||||||
|
<property name="authenticationContext">
|
||||||
|
<ref bean="authenticationContext" />
|
||||||
|
</property>
|
||||||
|
<property name="actionTrackingService">
|
||||||
|
<ref bean="actionTrackingService" />
|
||||||
|
</property>
|
||||||
|
<property name="dictionaryService">
|
||||||
|
<ref bean="DictionaryService" />
|
||||||
|
</property>
|
||||||
|
<property name="monitor">
|
||||||
|
<ref bean="actionServiceMonitor"/>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
</beans>
|
</beans>
|
||||||
|
Reference in New Issue
Block a user