From 43480468afda841aaaabcb464cfdf0ec6e8ea8de Mon Sep 17 00:00:00 2001
From: Marcin Strankowski <74721865+mstrankowski@users.noreply.github.com>
Date: Wed, 6 Jul 2022 16:07:40 +0200
Subject: [PATCH] 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
---
.../test/resources/test-context.xml | 1 +
.../AbstractExecuteActionWebscript.java | 52 +++---
.../scripts/rule/AbstractRuleWebScript.java | 76 +++++----
.../web/scripts/rule/ActionQueuePost.java | 52 +++---
.../alfresco/rest/api/impl/ActionsImpl.java | 4 +-
.../web-scripts-application-context.xml | 1 +
.../repo/action/ActionServiceImpl.java | 28 +++-
.../repo/action/RuntimeActionService.java | 57 ++++---
.../action/access/ActionAccessException.java | 34 ++++
.../access/ActionAccessRestriction.java | 53 ++++++
.../ActionAccessRestrictionAbstractBase.java | 157 ++++++++++++++++++
.../access/AdminActionAccessRestriction.java | 53 ++++++
.../repo/action/executer/ActionExecuter.java | 11 +-
.../executer/ActionExecuterAbstractBase.java | 33 +++-
.../executer/CompositeActionExecuter.java | 59 ++++---
.../processor/action/ActionFormProcessor.java | 52 +++---
.../alfresco/repo/rule/RuleServiceImpl.java | 64 +++----
.../service/cmr/action/ActionService.java | 53 +++---
.../alfresco/action-services-context.xml | 18 ++
.../OutboundSMTP/outboundSMTP-context.xml | 5 +-
.../outbound/outboundSMTP-test-context.xml | 3 +
21 files changed, 646 insertions(+), 220 deletions(-)
create mode 100644 repository/src/main/java/org/alfresco/repo/action/access/ActionAccessException.java
create mode 100644 repository/src/main/java/org/alfresco/repo/action/access/ActionAccessRestriction.java
create mode 100644 repository/src/main/java/org/alfresco/repo/action/access/ActionAccessRestrictionAbstractBase.java
create mode 100644 repository/src/main/java/org/alfresco/repo/action/access/AdminActionAccessRestriction.java
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 @@
+
+
+