diff --git a/amps/ags/rm-community/rm-community-repo/test/resources/test-context.xml b/amps/ags/rm-community/rm-community-repo/test/resources/test-context.xml index 0e6459074d..6f5dabc478 100644 --- a/amps/ags/rm-community/rm-community-repo/test/resources/test-context.xml +++ b/amps/ags/rm-community/rm-community-repo/test/resources/test-context.xml @@ -168,6 +168,7 @@ + diff --git a/remote-api/src/main/java/org/alfresco/repo/web/scripts/action/AbstractExecuteActionWebscript.java b/remote-api/src/main/java/org/alfresco/repo/web/scripts/action/AbstractExecuteActionWebscript.java index 227fea4194..5e9cb5c56c 100644 --- a/remote-api/src/main/java/org/alfresco/repo/web/scripts/action/AbstractExecuteActionWebscript.java +++ b/remote-api/src/main/java/org/alfresco/repo/web/scripts/action/AbstractExecuteActionWebscript.java @@ -1,32 +1,33 @@ -/* - * #%L - * Alfresco Remote API - * %% - * Copyright (C) 2005 - 2016 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% - */ +/* + * #%L + * Alfresco Remote API + * %% + * 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.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 diff --git a/remote-api/src/main/java/org/alfresco/repo/web/scripts/rule/AbstractRuleWebScript.java b/remote-api/src/main/java/org/alfresco/repo/web/scripts/rule/AbstractRuleWebScript.java index c86901bacd..9ad634fcfb 100644 --- a/remote-api/src/main/java/org/alfresco/repo/web/scripts/rule/AbstractRuleWebScript.java +++ b/remote-api/src/main/java/org/alfresco/repo/web/scripts/rule/AbstractRuleWebScript.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Remote API - * %% - * Copyright (C) 2005 - 2016 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% - */ +/* + * #%L + * Alfresco Remote API + * %% + * 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.web.scripts.rule; import java.io.Serializable; @@ -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 ruleTypes = rule.getRuleTypes(); - if (ruleTypes.contains(RULE_OUTBOUND)) + List actions = ((CompositeActionImpl) rule.getAction()).getActions(); + + checkRestrictedAccessActions(actions); + checkRuleOutboundHasNoCheckOutAction(rule, actions); + } + + private void checkRestrictedAccessActions(List actions) { + for (Action action : actions) { + ActionAccessRestriction.setActionContext(action, ActionAccessRestriction.RULE_ACTION_CONTEXT); + runtimeActionService.verifyActionAccessRestrictions(action); + } + } + + private void checkRuleOutboundHasNoCheckOutAction(Rule rule, List actions) { + if (rule.getRuleTypes().contains(RULE_OUTBOUND)) { - List actions = ((CompositeActionImpl) rule.getAction()).getActions(); for (Action action : actions) { if (action.getActionDefinitionName().equalsIgnoreCase(ACTION_CHECK_OUT)) diff --git a/remote-api/src/main/java/org/alfresco/repo/web/scripts/rule/ActionQueuePost.java b/remote-api/src/main/java/org/alfresco/repo/web/scripts/rule/ActionQueuePost.java index 496ba03489..b0b7de5f40 100644 --- a/remote-api/src/main/java/org/alfresco/repo/web/scripts/rule/ActionQueuePost.java +++ b/remote-api/src/main/java/org/alfresco/repo/web/scripts/rule/ActionQueuePost.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Remote API - * %% - * Copyright (C) 2005 - 2016 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% - */ +/* + * #%L + * Alfresco Remote API + * %% + * 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.web.scripts.rule; import java.io.IOException; @@ -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 diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/ActionsImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/ActionsImpl.java index 8c89fb7a2e..2bc272ba0b 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/ActionsImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/ActionsImpl.java @@ -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. diff --git a/remote-api/src/main/resources/alfresco/web-scripts-application-context.xml b/remote-api/src/main/resources/alfresco/web-scripts-application-context.xml index 4c4402c694..47d5358de3 100644 --- a/remote-api/src/main/resources/alfresco/web-scripts-application-context.xml +++ b/remote-api/src/main/resources/alfresco/web-scripts-application-context.xml @@ -696,6 +696,7 @@ + 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..fce14507df 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 @@ -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 actionDefinitions = new HashMap(); + /** + * Action access restricted executers + */ + private Map actionExecuters = new HashMap<>(); + /** * All the parameter constraints */ @@ -298,7 +304,7 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A */ public List getActionDefinitions() { - return new ArrayList(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) 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..7658b6b5a4 100644 --- a/repository/src/main/java/org/alfresco/repo/action/RuntimeActionService.java +++ b/repository/src/main/java/org/alfresco/repo/action/RuntimeActionService.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Repository - * %% - * Copyright (C) 2005 - 2016 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% - */ +/* + * #%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 java.util.Set; @@ -95,6 +95,13 @@ public interface RuntimeActionService * @param action the action */ 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 diff --git a/repository/src/main/java/org/alfresco/repo/action/access/ActionAccessException.java b/repository/src/main/java/org/alfresco/repo/action/access/ActionAccessException.java new file mode 100644 index 0000000000..898db9b76b --- /dev/null +++ b/repository/src/main/java/org/alfresco/repo/action/access/ActionAccessException.java @@ -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 . + * #L% + */ + +package org.alfresco.repo.action.access; + +public class ActionAccessException extends RuntimeException { + + public ActionAccessException(String message) { + super(message); + } +} diff --git a/repository/src/main/java/org/alfresco/repo/action/access/ActionAccessRestriction.java b/repository/src/main/java/org/alfresco/repo/action/access/ActionAccessRestriction.java new file mode 100644 index 0000000000..4e303435b0 --- /dev/null +++ b/repository/src/main/java/org/alfresco/repo/action/access/ActionAccessRestriction.java @@ -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 . + * #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); +} diff --git a/repository/src/main/java/org/alfresco/repo/action/access/ActionAccessRestrictionAbstractBase.java b/repository/src/main/java/org/alfresco/repo/action/access/ActionAccessRestrictionAbstractBase.java new file mode 100644 index 0000000000..0139d7515b --- /dev/null +++ b/repository/src/main/java/org/alfresco/repo/action/access/ActionAccessRestrictionAbstractBase.java @@ -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 . + * #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 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 isExposedInConfig(Action action) + { + return getConfigKeys(action). + map(configProperties::getProperty). + filter(Objects::nonNull). + map(Boolean::parseBoolean). + findFirst(); + } + + private Stream 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); +} diff --git a/repository/src/main/java/org/alfresco/repo/action/access/AdminActionAccessRestriction.java b/repository/src/main/java/org/alfresco/repo/action/access/AdminActionAccessRestriction.java new file mode 100644 index 0000000000..4173ce69cf --- /dev/null +++ b/repository/src/main/java/org/alfresco/repo/action/access/AdminActionAccessRestriction.java @@ -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 . + * #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"); + } + } +} diff --git a/repository/src/main/java/org/alfresco/repo/action/executer/ActionExecuter.java b/repository/src/main/java/org/alfresco/repo/action/executer/ActionExecuter.java index d8f0957a6a..d405668462 100644 --- a/repository/src/main/java/org/alfresco/repo/action/executer/ActionExecuter.java +++ b/repository/src/main/java/org/alfresco/repo/action/executer/ActionExecuter.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 @@ -76,6 +76,15 @@ public interface ActionExecuter * @return the action definition */ 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 diff --git a/repository/src/main/java/org/alfresco/repo/action/executer/ActionExecuterAbstractBase.java b/repository/src/main/java/org/alfresco/repo/action/executer/ActionExecuterAbstractBase.java index d6c27a42c5..653ab0b537 100644 --- a/repository/src/main/java/org/alfresco/repo/action/executer/ActionExecuterAbstractBase.java +++ b/repository/src/main/java/org/alfresco/repo/action/executer/ActionExecuterAbstractBase.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,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; @@ -64,6 +67,9 @@ public abstract class ActionExecuterAbstractBase extends ParameterizedItemAbstra /** Indicated whether the action is public or internal (default true) */ protected boolean publicAction = true; + + /** List of action access restrictions (default empty list */ + protected List actionAccessRestrictions = new ArrayList<>(); /** List of types and aspects for which this action is applicable */ protected Set applicableTypes = new HashSet(); @@ -79,7 +85,7 @@ public abstract class ActionExecuterAbstractBase extends ParameterizedItemAbstra */ public void init() { - if (this.publicAction == true) + if (this.publicAction) { this.runtimeActionService.registerActionExecuter(this); } @@ -109,7 +115,7 @@ public abstract class ActionExecuterAbstractBase extends ParameterizedItemAbstra { this.dictionaryService = dictionaryService; } - + /** * Set whether the action is public or not. * @@ -120,6 +126,19 @@ public abstract class ActionExecuterAbstractBase extends ParameterizedItemAbstra this.publicAction = publicAction; } + /** + * Set action access restrictions + * + * @param actionAccessRestrictions + */ + public void setActionAccessRestrictions(List actionAccessRestrictions) { + this.actionAccessRestrictions = actionAccessRestrictions; + } + + public List 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 @@ -282,6 +302,13 @@ public abstract class ActionExecuterAbstractBase extends ParameterizedItemAbstra } } } + + /** + * {@inheritDoc} + */ + public void verifyActionAccessRestrictions(Action action) { + actionAccessRestrictions.forEach(ar -> ar.verifyAccessRestriction(action)); + } /** * Execute the action implementation diff --git a/repository/src/main/java/org/alfresco/repo/action/executer/CompositeActionExecuter.java b/repository/src/main/java/org/alfresco/repo/action/executer/CompositeActionExecuter.java index 961bd56f3e..94c9b01bc6 100644 --- a/repository/src/main/java/org/alfresco/repo/action/executer/CompositeActionExecuter.java +++ b/repository/src/main/java/org/alfresco/repo/action/executer/CompositeActionExecuter.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Repository - * %% - * Copyright (C) 2005 - 2016 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% - */ +/* + * #%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.executer; import java.util.List; @@ -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) */ diff --git a/repository/src/main/java/org/alfresco/repo/forms/processor/action/ActionFormProcessor.java b/repository/src/main/java/org/alfresco/repo/forms/processor/action/ActionFormProcessor.java index 10177d8a32..6befbef50f 100644 --- a/repository/src/main/java/org/alfresco/repo/forms/processor/action/ActionFormProcessor.java +++ b/repository/src/main/java/org/alfresco/repo/forms/processor/action/ActionFormProcessor.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Repository - * %% - * Copyright (C) 2005 - 2016 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% - */ +/* + * #%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.forms.processor.action; @@ -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. - * #L% - */ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2016 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.rule; import java.io.Serializable; @@ -1362,13 +1362,13 @@ public class RuleServiceImpl return result; } - /** - * Register the rule type - * - * @param ruleType the rule type adapter - */ - public void registerRuleType(RuleType ruleType) - { + /** + * Register the rule type + * + * @param ruleType the rule type adapter + */ + public void registerRuleType(RuleType ruleType) + { this.ruleTypes.put(ruleType.getName(), ruleType); } diff --git a/repository/src/main/java/org/alfresco/service/cmr/action/ActionService.java b/repository/src/main/java/org/alfresco/service/cmr/action/ActionService.java index 1406c9f509..e4ca16183a 100644 --- a/repository/src/main/java/org/alfresco/service/cmr/action/ActionService.java +++ b/repository/src/main/java/org/alfresco/service/cmr/action/ActionService.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Repository - * %% - * Copyright (C) 2005 - 2016 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% - */ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2016 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.service.cmr.action; import java.io.Serializable; @@ -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; /** @@ -155,7 +154,7 @@ public interface ActionService */ @Auditable() CompositeActionCondition createCompositeActionCondition(); - + /** * The actions conditions are always checked. * diff --git a/repository/src/main/resources/alfresco/action-services-context.xml b/repository/src/main/resources/alfresco/action-services-context.xml index 69d521e9a3..14c3b407ca 100644 --- a/repository/src/main/resources/alfresco/action-services-context.xml +++ b/repository/src/main/resources/alfresco/action-services-context.xml @@ -527,6 +527,7 @@ org.alfresco.repo.action.executer.ActionExecuter org.alfresco.repo.action.executer.TestModeable + org.alfresco.repo.action.executer.LoggingAwareExecuter @@ -768,5 +769,22 @@ + + + + + + + + + + + + + + + + + diff --git a/repository/src/main/resources/alfresco/subsystems/email/OutboundSMTP/outboundSMTP-context.xml b/repository/src/main/resources/alfresco/subsystems/email/OutboundSMTP/outboundSMTP-context.xml index be349b7b47..02b927a0b1 100755 --- a/repository/src/main/resources/alfresco/subsystems/email/OutboundSMTP/outboundSMTP-context.xml +++ b/repository/src/main/resources/alfresco/subsystems/email/OutboundSMTP/outboundSMTP-context.xml @@ -46,7 +46,10 @@ - + + + + diff --git a/repository/src/test/resources/alfresco/extension/subsystems/email/OutboundSMTP/outbound/outboundSMTP-test-context.xml b/repository/src/test/resources/alfresco/extension/subsystems/email/OutboundSMTP/outbound/outboundSMTP-test-context.xml index 549f670f95..ac67ac943d 100755 --- a/repository/src/test/resources/alfresco/extension/subsystems/email/OutboundSMTP/outbound/outboundSMTP-test-context.xml +++ b/repository/src/test/resources/alfresco/extension/subsystems/email/OutboundSMTP/outbound/outboundSMTP-test-context.xml @@ -5,6 +5,9 @@ + + +