mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Feature/acs 3169 implement security mechanism for mail action (#1189)
Implementing access restriction for actions Updating copyrights of modified files Moving core restriction processing to an AbstractBase class PR Review fixes Slight improvement for future extensibility
This commit is contained in:
committed by
GitHub
parent
92d010842a
commit
43480468af
@@ -168,6 +168,7 @@
|
||||
<property name="nodeService" ref="NodeService"/>
|
||||
<property name="ruleService" ref="RuleService"/>
|
||||
<property name="actionService" ref="ActionService"/>
|
||||
<property name="runtimeActionService" ref="actionService"/>
|
||||
<property name="dictionaryService" ref="DictionaryService"/>
|
||||
<property name="fileFolderService" ref="FileFolderService"/>
|
||||
<property name="namespaceService" ref="NamespaceService" />
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* 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
|
||||
@@ -27,6 +27,7 @@ package org.alfresco.repo.web.scripts.action;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.action.access.ActionAccessRestriction;
|
||||
import org.alfresco.service.cmr.action.Action;
|
||||
import org.alfresco.service.cmr.action.ExecutionSummary;
|
||||
import org.springframework.extensions.webscripts.Cache;
|
||||
@@ -58,6 +59,7 @@ public abstract class AbstractExecuteActionWebscript extends AbstractActionWebsc
|
||||
|
||||
// Ask for it to be run in the background
|
||||
// It will be available to execute once the webscript finishes
|
||||
ActionAccessRestriction.setActionContext(action, ActionAccessRestriction.V0_ACTION_CONTEXT);
|
||||
actionService.executeAction(
|
||||
action, null,
|
||||
false, true
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* 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
|
||||
@@ -38,6 +38,8 @@ import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.action.ActionConditionImpl;
|
||||
import org.alfresco.repo.action.ActionImpl;
|
||||
import org.alfresco.repo.action.CompositeActionImpl;
|
||||
import org.alfresco.repo.action.RuntimeActionService;
|
||||
import org.alfresco.repo.action.access.ActionAccessRestriction;
|
||||
import org.alfresco.service.cmr.action.Action;
|
||||
import org.alfresco.service.cmr.action.ActionCondition;
|
||||
import org.alfresco.service.cmr.action.ActionService;
|
||||
@@ -85,6 +87,8 @@ public abstract class AbstractRuleWebScript extends DeclarativeWebScript
|
||||
protected FileFolderService fileFolderService;
|
||||
protected NamespaceService namespaceService;
|
||||
|
||||
private RuntimeActionService runtimeActionService;
|
||||
|
||||
/**
|
||||
* Sets the node service instance
|
||||
*
|
||||
@@ -145,6 +149,10 @@ public abstract class AbstractRuleWebScript extends DeclarativeWebScript
|
||||
this.namespaceService = namespaceService;
|
||||
}
|
||||
|
||||
public void setRuntimeActionService(RuntimeActionService runtimeActionService) {
|
||||
this.runtimeActionService = runtimeActionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the request and providing it's valid returns the NodeRef.
|
||||
*
|
||||
@@ -432,10 +440,22 @@ public abstract class AbstractRuleWebScript extends DeclarativeWebScript
|
||||
|
||||
protected void checkRule(Rule rule)
|
||||
{
|
||||
List<String> ruleTypes = rule.getRuleTypes();
|
||||
if (ruleTypes.contains(RULE_OUTBOUND))
|
||||
List<Action> actions = ((CompositeActionImpl) rule.getAction()).getActions();
|
||||
|
||||
checkRestrictedAccessActions(actions);
|
||||
checkRuleOutboundHasNoCheckOutAction(rule, actions);
|
||||
}
|
||||
|
||||
private void checkRestrictedAccessActions(List<Action> actions) {
|
||||
for (Action action : actions) {
|
||||
ActionAccessRestriction.setActionContext(action, ActionAccessRestriction.RULE_ACTION_CONTEXT);
|
||||
runtimeActionService.verifyActionAccessRestrictions(action);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkRuleOutboundHasNoCheckOutAction(Rule rule, List<Action> actions) {
|
||||
if (rule.getRuleTypes().contains(RULE_OUTBOUND))
|
||||
{
|
||||
List<Action> actions = ((CompositeActionImpl) rule.getAction()).getActions();
|
||||
for (Action action : actions)
|
||||
{
|
||||
if (action.getActionDefinitionName().equalsIgnoreCase(ACTION_CHECK_OUT))
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* 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
|
||||
@@ -30,6 +30,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.action.ActionImpl;
|
||||
import org.alfresco.repo.action.access.ActionAccessRestriction;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -89,6 +90,7 @@ public class ActionQueuePost extends AbstractRuleWebScript
|
||||
}
|
||||
|
||||
// Execute action
|
||||
ActionAccessRestriction.setActionContext(action, ActionAccessRestriction.V0_ACTION_CONTEXT);
|
||||
actionService.executeAction(action, actionedUponNode, true, async);
|
||||
|
||||
// Prepair model
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2017 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
|
||||
@@ -26,6 +26,7 @@
|
||||
package org.alfresco.rest.api.impl;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.action.access.ActionAccessRestriction;
|
||||
import org.alfresco.rest.api.Actions;
|
||||
import org.alfresco.rest.api.model.Action;
|
||||
import org.alfresco.rest.api.model.ActionDefinition;
|
||||
@@ -286,6 +287,7 @@ public class ActionsImpl implements Actions
|
||||
cmrAction = actionService.createAction(action.getActionDefinitionId());
|
||||
}
|
||||
|
||||
ActionAccessRestriction.setActionContext(cmrAction, ActionAccessRestriction.V1_ACTION_CONTEXT);
|
||||
actionService.executeAction(cmrAction, actionedUponNodeRef, true, true);
|
||||
|
||||
// Create user result.
|
||||
|
@@ -696,6 +696,7 @@
|
||||
<property name="nodeService" ref="NodeService"/>
|
||||
<property name="ruleService" ref="RuleService"/>
|
||||
<property name="actionService" ref="ActionService"/>
|
||||
<property name="runtimeActionService" ref="actionService"/>
|
||||
<property name="dictionaryService" ref="DictionaryService"/>
|
||||
<property name="fileFolderService" ref="FileFolderService"/>
|
||||
<property name="namespaceService" ref="NamespaceService" />
|
||||
|
@@ -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
|
||||
@@ -36,6 +36,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.action.access.ActionAccessRestriction;
|
||||
import org.alfresco.repo.action.evaluator.ActionConditionEvaluator;
|
||||
import org.alfresco.repo.action.executer.ActionExecuter;
|
||||
import org.alfresco.repo.action.executer.CompositeActionExecuter;
|
||||
@@ -141,6 +142,11 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
|
||||
*/
|
||||
private Map<String, ActionDefinition> actionDefinitions = new HashMap<String, ActionDefinition>();
|
||||
|
||||
/**
|
||||
* Action access restricted executers
|
||||
*/
|
||||
private Map<String, ActionExecuter> actionExecuters = new HashMap<>();
|
||||
|
||||
/**
|
||||
* All the parameter constraints
|
||||
*/
|
||||
@@ -298,7 +304,7 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
|
||||
*/
|
||||
public List<ActionDefinition> getActionDefinitions()
|
||||
{
|
||||
return new ArrayList<ActionDefinition>(this.actionDefinitions.values());
|
||||
return new ArrayList<>(this.actionDefinitions.values());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -588,11 +594,29 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
|
||||
}
|
||||
else
|
||||
{
|
||||
verifyActionAccessRestrictions(action);
|
||||
// Add to the post transaction pending action list
|
||||
addPostTransactionPendingAction(action, actionedUponNodeRef, checkConditions, actionChain);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RuntimeActionService#verifyActionAccessRestrictions(Action action)
|
||||
*/
|
||||
@Override
|
||||
public void verifyActionAccessRestrictions(Action action) {
|
||||
getActionExecuter(action.getActionDefinitionName())
|
||||
.verifyActionAccessRestrictions(action);
|
||||
}
|
||||
|
||||
private ActionExecuter getActionExecuter(String actionDefName) {
|
||||
if (!actionExecuters.containsKey(actionDefName)) {
|
||||
actionExecuters.put(actionDefName, applicationContext.getBean(actionDefName, ActionExecuter.class));
|
||||
}
|
||||
|
||||
return actionExecuters.get(actionDefName);
|
||||
}
|
||||
|
||||
private boolean isExecuteAsynchronously(Action action, NodeRef actionedUponNodeRef, boolean executeAsynchronously)
|
||||
{
|
||||
if (executeAsynchronously == false)
|
||||
|
@@ -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
|
||||
@@ -96,6 +96,13 @@ public interface RuntimeActionService
|
||||
*/
|
||||
void saveActionImpl(NodeRef actionNodeRef, Action action);
|
||||
|
||||
/**
|
||||
* Verify users access to an action with restrictions
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
void verifyActionAccessRestrictions(Action action);
|
||||
|
||||
/**
|
||||
* Perform low-level action execution
|
||||
*/
|
||||
|
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* #%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.access;
|
||||
|
||||
public class ActionAccessException extends RuntimeException {
|
||||
|
||||
public ActionAccessException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* #%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.access;
|
||||
|
||||
import org.alfresco.service.cmr.action.Action;
|
||||
|
||||
public interface ActionAccessRestriction {
|
||||
|
||||
String ACTION_CONTEXT_PARAM_NAME = "actionContext";
|
||||
String RULE_ACTION_CONTEXT = "rule";
|
||||
String FORM_PROCESSOR_ACTION_CONTEXT = "formProcessor";
|
||||
String V0_ACTION_CONTEXT = "v0";
|
||||
String V1_ACTION_CONTEXT = "v1";
|
||||
|
||||
static void setActionContext(Action action, String actionContext) {
|
||||
action.setParameterValue(ACTION_CONTEXT_PARAM_NAME, actionContext);
|
||||
}
|
||||
|
||||
static String getActionContext(Action action) {
|
||||
return (String) action.getParameterValue(ACTION_CONTEXT_PARAM_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify action access restriction
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
void verifyAccessRestriction(Action action);
|
||||
}
|
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* #%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.access;
|
||||
|
||||
import org.alfresco.repo.action.ActionModel;
|
||||
import org.alfresco.repo.rule.RuleModel;
|
||||
import org.alfresco.service.cmr.action.Action;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public abstract class ActionAccessRestrictionAbstractBase implements ActionAccessRestriction {
|
||||
|
||||
private static final Set<String> CONTROLLED_ACTION_ACCESS_CONTEXT =
|
||||
Set.of(ActionAccessRestriction.RULE_ACTION_CONTEXT, ActionAccessRestriction.FORM_PROCESSOR_ACTION_CONTEXT,
|
||||
ActionAccessRestriction.V0_ACTION_CONTEXT, ActionAccessRestriction.V1_ACTION_CONTEXT);
|
||||
|
||||
protected NodeService nodeService;
|
||||
private Properties configProperties;
|
||||
|
||||
|
||||
public void setNodeService(NodeService nodeService) {
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
public void setConfigProperties(Properties configProperties) {
|
||||
this.configProperties = configProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base for verifying access restriction,
|
||||
* manages common checks for exposing action in config or action being ran as a consequence of running a rule (safe)
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
public void verifyAccessRestriction(Action action) {
|
||||
if (blockAccessRestriction(action)) {
|
||||
return;
|
||||
}
|
||||
|
||||
innerVerifyAccessRestriction(action);
|
||||
}
|
||||
|
||||
protected boolean blockAccessRestriction(Action action) {
|
||||
return isActionExposed(action) || isActionCausedByRule(action);
|
||||
}
|
||||
|
||||
protected boolean isActionExposed(Action action) {
|
||||
return !isActionFromControlledContext(action) || isExposedInConfig(action).orElse(Boolean.FALSE);
|
||||
}
|
||||
|
||||
private boolean isActionFromControlledContext(Action action) {
|
||||
String actionContext = ActionAccessRestriction.getActionContext(action);
|
||||
return actionContext != null && CONTROLLED_ACTION_ACCESS_CONTEXT.contains(actionContext);
|
||||
}
|
||||
|
||||
private Optional<Boolean> isExposedInConfig(Action action)
|
||||
{
|
||||
return getConfigKeys(action).
|
||||
map(configProperties::getProperty).
|
||||
filter(Objects::nonNull).
|
||||
map(Boolean::parseBoolean).
|
||||
findFirst();
|
||||
}
|
||||
|
||||
private Stream<String> getConfigKeys(Action action)
|
||||
{
|
||||
String context = ActionAccessRestriction.getActionContext(action);
|
||||
String actionName = action.getActionDefinitionName();
|
||||
|
||||
if (context != null)
|
||||
{
|
||||
return Stream.of(
|
||||
getConfigKey(context, actionName),
|
||||
getConfigKey(context));
|
||||
}
|
||||
return Stream.of(getConfigKey(actionName));
|
||||
}
|
||||
|
||||
private String getConfigKey(String... parts)
|
||||
{
|
||||
return Stream.of(parts)
|
||||
.collect(Collectors.joining(".", "org.alfresco.repo.action.", ".exposed"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the hierarchy of primary parents of action node ref to look for Rule node ref
|
||||
* Finding it means that the action was triggered by an existing rule, which are deemed secure
|
||||
* as their validation happens at their setup.
|
||||
*
|
||||
* @param action
|
||||
* @return
|
||||
*/
|
||||
protected boolean isActionCausedByRule(Action action) {
|
||||
if (action.getNodeRef() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NodeRef ruleParent = getPotentialRuleParent(action.getNodeRef());
|
||||
return isRule(ruleParent);
|
||||
}
|
||||
|
||||
private NodeRef getPotentialRuleParent(NodeRef nodeRef) {
|
||||
NodeRef parentNode = nodeService.getPrimaryParent(nodeRef).getParentRef();
|
||||
|
||||
while (isCompositeAction(parentNode))
|
||||
{
|
||||
parentNode = nodeService.getPrimaryParent(parentNode).getParentRef();
|
||||
}
|
||||
|
||||
return parentNode;
|
||||
}
|
||||
|
||||
private boolean isCompositeAction(NodeRef nodeRef) {
|
||||
return ActionModel.TYPE_COMPOSITE_ACTION.equals(nodeService.getType(nodeRef));
|
||||
}
|
||||
|
||||
private boolean isRule(NodeRef nodeRef) {
|
||||
return RuleModel.TYPE_RULE.equals(nodeService.getType(nodeRef));
|
||||
}
|
||||
|
||||
/**
|
||||
* Restriction specific implementation of extensions
|
||||
* @param action
|
||||
*/
|
||||
protected abstract void innerVerifyAccessRestriction(Action action);
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* #%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.access;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.service.cmr.action.Action;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
|
||||
public class AdminActionAccessRestriction extends ActionAccessRestrictionAbstractBase {
|
||||
|
||||
private AuthorityService authorityService;
|
||||
|
||||
public void setAuthorityService(AuthorityService authorityService) {
|
||||
this.authorityService = authorityService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only admin can run action access restriction
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
protected void innerVerifyAccessRestriction(Action action) {
|
||||
boolean isAdminOrSystemUser = authorityService.hasAdminAuthority() || AuthenticationUtil.isRunAsUserTheSystemUser();
|
||||
if (!isAdminOrSystemUser) {
|
||||
throw new ActionAccessException("Only admin or system user is allowed to define uses of " +
|
||||
"or directly execute this action");
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
@@ -77,6 +77,15 @@ public interface ActionExecuter
|
||||
*/
|
||||
ActionDefinition getActionDefinition();
|
||||
|
||||
/**
|
||||
* Verify action access restrictions
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
default void verifyActionAccessRestrictions(Action action){
|
||||
//Will be extended by ActionExecutor implementation, to provide security if needed
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute the action executer
|
||||
*
|
||||
|
@@ -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,12 +25,15 @@
|
||||
*/
|
||||
package org.alfresco.repo.action.executer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.api.AlfrescoPublicApi;
|
||||
import org.alfresco.repo.action.ActionDefinitionImpl;
|
||||
import org.alfresco.repo.action.ParameterizedItemAbstractBase;
|
||||
import org.alfresco.repo.action.access.ActionAccessRestriction;
|
||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
|
||||
import org.alfresco.service.cmr.action.Action;
|
||||
@@ -65,6 +68,9 @@ public abstract class ActionExecuterAbstractBase extends ParameterizedItemAbstra
|
||||
/** Indicated whether the action is public or internal (default <tt>true</tt>) */
|
||||
protected boolean publicAction = true;
|
||||
|
||||
/** List of action access restrictions (default <tt>empty list</tt> */
|
||||
protected List<ActionAccessRestriction> actionAccessRestrictions = new ArrayList<>();
|
||||
|
||||
/** List of types and aspects for which this action is applicable */
|
||||
protected Set<QName> applicableTypes = new HashSet<QName>();
|
||||
|
||||
@@ -79,7 +85,7 @@ public abstract class ActionExecuterAbstractBase extends ParameterizedItemAbstra
|
||||
*/
|
||||
public void init()
|
||||
{
|
||||
if (this.publicAction == true)
|
||||
if (this.publicAction)
|
||||
{
|
||||
this.runtimeActionService.registerActionExecuter(this);
|
||||
}
|
||||
@@ -120,6 +126,19 @@ public abstract class ActionExecuterAbstractBase extends ParameterizedItemAbstra
|
||||
this.publicAction = publicAction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set action access restrictions
|
||||
*
|
||||
* @param actionAccessRestrictions
|
||||
*/
|
||||
public void setActionAccessRestrictions(List<ActionAccessRestriction> actionAccessRestrictions) {
|
||||
this.actionAccessRestrictions = actionAccessRestrictions;
|
||||
}
|
||||
|
||||
public List<ActionAccessRestriction> getActionAccessRestrictions() {
|
||||
return actionAccessRestrictions;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@@ -270,6 +289,7 @@ public abstract class ActionExecuterAbstractBase extends ParameterizedItemAbstra
|
||||
if ( !nodeIsLockedForThisUser)
|
||||
{
|
||||
// Execute the implementation
|
||||
verifyActionAccessRestrictions(action);
|
||||
executeImpl(action, actionedUponNodeRef);
|
||||
}
|
||||
else
|
||||
@@ -283,6 +303,13 @@ public abstract class ActionExecuterAbstractBase extends ParameterizedItemAbstra
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void verifyActionAccessRestrictions(Action action) {
|
||||
actionAccessRestrictions.forEach(ar -> ar.verifyAccessRestriction(action));
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action implementation
|
||||
*
|
||||
|
@@ -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
|
||||
@@ -60,6 +60,15 @@ public class CompositeActionExecuter extends ActionExecuterAbstractBase
|
||||
this.actionService = actionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void verifyActionAccessRestrictions(Action action) {
|
||||
for (Action subAction : ((CompositeAction)action).getActions()) {
|
||||
this.actionService.verifyActionAccessRestrictions(subAction);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.action.executer.ActionExecuter#execute(Action, NodeRef)
|
||||
*/
|
||||
|
@@ -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
|
||||
@@ -37,6 +37,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.alfresco.repo.action.access.ActionAccessRestriction;
|
||||
import org.alfresco.repo.action.executer.ActionExecuter;
|
||||
import org.alfresco.repo.forms.Field;
|
||||
import org.alfresco.repo.forms.FormData;
|
||||
@@ -164,6 +165,7 @@ public class ActionFormProcessor extends FilteredFormProcessor<ActionDefinition,
|
||||
final boolean isAsync = isAsynchronousActionRequest(item, data);
|
||||
|
||||
// execute the action
|
||||
ActionAccessRestriction.setActionContext(actionToExecute, ActionAccessRestriction.FORM_PROCESSOR_ACTION_CONTEXT);
|
||||
actionService.executeAction(actionToExecute, actionedUponNodeRef, true, isAsync);
|
||||
|
||||
// extract the result
|
||||
|
@@ -31,7 +31,6 @@ import java.util.Map;
|
||||
|
||||
import org.alfresco.api.AlfrescoPublicApi;
|
||||
import org.alfresco.service.Auditable;
|
||||
import org.alfresco.service.PublicService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
/**
|
||||
|
@@ -527,6 +527,7 @@
|
||||
<list>
|
||||
<value>org.alfresco.repo.action.executer.ActionExecuter</value>
|
||||
<value>org.alfresco.repo.action.executer.TestModeable</value>
|
||||
<value>org.alfresco.repo.action.executer.LoggingAwareExecuter</value>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
@@ -769,4 +770,21 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Action Restriction Beans -->
|
||||
|
||||
<bean id="actionAccessRestrictionBase" abstract="true" class="org.alfresco.repo.action.access.ActionAccessRestrictionAbstractBase">
|
||||
<property name="nodeService">
|
||||
<ref bean="NodeService"/>
|
||||
</property>
|
||||
<property name="configProperties">
|
||||
<ref bean="global-properties" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="adminActionAccessRestriction" class="org.alfresco.repo.action.access.AdminActionAccessRestriction" parent="actionAccessRestrictionBase">
|
||||
<property name="authorityService">
|
||||
<ref bean="AuthorityService" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
@@ -46,7 +46,10 @@
|
||||
</bean>
|
||||
|
||||
<bean id="mail" class="org.alfresco.repo.action.executer.MailActionExecuter" parent="action-executer">
|
||||
<property name="queueName" value="outboundMail"/>
|
||||
<property name="actionAccessRestrictions">
|
||||
<ref bean="adminActionAccessRestriction"/>
|
||||
</property>
|
||||
<property name="queueName" value="outboundMail"/>
|
||||
<property name="mailService">
|
||||
<ref bean="mailService"></ref>
|
||||
</property>
|
||||
|
@@ -5,6 +5,9 @@
|
||||
<!-- This bean, which should only be used during Unit Tests, overrides the "mail" bean such that
|
||||
it sets the testMode to true. -->
|
||||
<bean id="mail" class="org.alfresco.util.email.ExtendedMailActionExecutor" parent="action-executer">
|
||||
<property name="actionAccessRestrictions">
|
||||
<ref bean="adminActionAccessRestriction"/>
|
||||
</property>
|
||||
<property name="queueName" value="outboundMail"/>
|
||||
<property name="mailService">
|
||||
<ref bean="mailService"></ref>
|
||||
|
Reference in New Issue
Block a user