mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-21 18:09:20 +00:00
Merged HEAD-BUG-FIX (4.3/Cloud) to HEAD (4.3/Cloud)
59121: Merged V4.2-BUG-FIX (4.2.1) to HEAD-BUG-FIX (Cloud/4.3) 59106: Merged DEV to V4.2-BUG-FIX (4.2.1) 57540: MNT-9883: Consumer can add document comments via API, bypasses UI security checks - Only users with 'AddChildren' permission can start discussions. 58305: MNT-9883: Consumer can add document comments via API, bypasses UI security checks - Add unit test git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@62101 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -29,10 +29,13 @@ import org.alfresco.repo.jscript.Scopeable;
|
|||||||
import org.alfresco.repo.jscript.ScriptNode;
|
import org.alfresco.repo.jscript.ScriptNode;
|
||||||
import org.alfresco.repo.policy.BehaviourFilter;
|
import org.alfresco.repo.policy.BehaviourFilter;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
|
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||||
import org.alfresco.service.ServiceRegistry;
|
import org.alfresco.service.ServiceRegistry;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.security.AccessStatus;
|
||||||
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||||
@@ -51,11 +54,13 @@ public class ScriptCommentService extends BaseScopableProcessorExtension
|
|||||||
private ServiceRegistry serviceRegistry;
|
private ServiceRegistry serviceRegistry;
|
||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
private BehaviourFilter behaviourFilter;
|
private BehaviourFilter behaviourFilter;
|
||||||
|
private PermissionService permissionService;
|
||||||
|
|
||||||
public void setServiceRegistry(ServiceRegistry serviceRegistry)
|
public void setServiceRegistry(ServiceRegistry serviceRegistry)
|
||||||
{
|
{
|
||||||
this.serviceRegistry = serviceRegistry;
|
this.serviceRegistry = serviceRegistry;
|
||||||
this.nodeService = serviceRegistry.getNodeService();
|
this.nodeService = serviceRegistry.getNodeService();
|
||||||
|
this.permissionService = serviceRegistry.getPermissionService();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBehaviourFilter(BehaviourFilter behaviourFilter)
|
public void setBehaviourFilter(BehaviourFilter behaviourFilter)
|
||||||
@@ -66,7 +71,12 @@ public class ScriptCommentService extends BaseScopableProcessorExtension
|
|||||||
public ScriptNode createCommentsFolder(ScriptNode node)
|
public ScriptNode createCommentsFolder(ScriptNode node)
|
||||||
{
|
{
|
||||||
final NodeRef nodeRef = node.getNodeRef();
|
final NodeRef nodeRef = node.getNodeRef();
|
||||||
|
if (permissionService.hasPermission(nodeRef, PermissionService.ADD_CHILDREN) == AccessStatus.DENIED)
|
||||||
|
{
|
||||||
|
throw new AccessDeniedException("User '" + AuthenticationUtil.getFullyAuthenticatedUser() + "' doesn't have permission to create discussion on node '" + nodeRef + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Run as system user to allow Contributor create discussions
|
||||||
NodeRef commentsFolder = AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<NodeRef>()
|
NodeRef commentsFolder = AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<NodeRef>()
|
||||||
{
|
{
|
||||||
public NodeRef doWork() throws Exception
|
public NodeRef doWork() throws Exception
|
||||||
|
@@ -7,18 +7,27 @@ import javax.transaction.UserTransaction;
|
|||||||
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
|
import org.alfresco.repo.security.permissions.PermissionReference;
|
||||||
|
import org.alfresco.repo.security.permissions.PermissionServiceSPI;
|
||||||
|
import org.alfresco.repo.security.permissions.impl.ModelDAO;
|
||||||
|
import org.alfresco.repo.security.permissions.impl.SimplePermissionEntry;
|
||||||
import org.alfresco.repo.web.scripts.BaseWebScriptTest;
|
import org.alfresco.repo.web.scripts.BaseWebScriptTest;
|
||||||
import org.alfresco.service.cmr.model.FileFolderService;
|
import org.alfresco.service.cmr.model.FileFolderService;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
import org.alfresco.service.cmr.search.SearchService;
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
|
import org.alfresco.service.cmr.security.AccessStatus;
|
||||||
|
import org.alfresco.service.cmr.security.MutableAuthenticationService;
|
||||||
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
import org.alfresco.service.cmr.version.VersionService;
|
import org.alfresco.service.cmr.version.VersionService;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
|
import org.alfresco.util.PropertyMap;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.extensions.webscripts.Status;
|
|
||||||
import org.springframework.extensions.webscripts.TestWebScriptServer.PostRequest;
|
import org.springframework.extensions.webscripts.TestWebScriptServer.PostRequest;
|
||||||
import org.springframework.extensions.webscripts.TestWebScriptServer.Response;
|
import org.springframework.extensions.webscripts.TestWebScriptServer.Response;
|
||||||
|
|
||||||
@@ -34,10 +43,18 @@ public class CommentsApiTest extends BaseWebScriptTest
|
|||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
private NamespaceService namespaceService;
|
private NamespaceService namespaceService;
|
||||||
private VersionService versionService;
|
private VersionService versionService;
|
||||||
|
private PersonService personService;
|
||||||
|
private MutableAuthenticationService authenticationService;
|
||||||
|
private AuthenticationComponent authenticationComponent;
|
||||||
|
protected PermissionServiceSPI permissionService;
|
||||||
|
protected ModelDAO permissionModelDAO;
|
||||||
|
|
||||||
private NodeRef rootNodeRef;
|
private NodeRef rootNodeRef;
|
||||||
|
private NodeRef companyHomeNodeRef;
|
||||||
private NodeRef nodeRef;
|
private NodeRef nodeRef;
|
||||||
|
|
||||||
|
private static final String USER_TEST = "UserTest";
|
||||||
|
|
||||||
private UserTransaction txn;
|
private UserTransaction txn;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -52,6 +69,11 @@ public class CommentsApiTest extends BaseWebScriptTest
|
|||||||
nodeService = (NodeService)appContext.getBean("nodeService");
|
nodeService = (NodeService)appContext.getBean("nodeService");
|
||||||
namespaceService = (NamespaceService)appContext.getBean("namespaceService");
|
namespaceService = (NamespaceService)appContext.getBean("namespaceService");
|
||||||
versionService = (VersionService)appContext.getBean("versionService");
|
versionService = (VersionService)appContext.getBean("versionService");
|
||||||
|
personService = (PersonService)getServer().getApplicationContext().getBean("PersonService");
|
||||||
|
authenticationService = (MutableAuthenticationService)getServer().getApplicationContext().getBean("AuthenticationService");
|
||||||
|
authenticationComponent = (AuthenticationComponent)getServer().getApplicationContext().getBean("authenticationComponent");
|
||||||
|
permissionService = (PermissionServiceSPI) getServer().getApplicationContext().getBean("permissionService");
|
||||||
|
permissionModelDAO = (ModelDAO) getServer().getApplicationContext().getBean("permissionsModelDAO");
|
||||||
|
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
||||||
|
|
||||||
@@ -65,7 +87,7 @@ public class CommentsApiTest extends BaseWebScriptTest
|
|||||||
throw new AlfrescoRuntimeException("Can't find /app:company_home");
|
throw new AlfrescoRuntimeException("Can't find /app:company_home");
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeRef companyHomeNodeRef = results.get(0);
|
companyHomeNodeRef = results.get(0);
|
||||||
|
|
||||||
results = searchService.selectNodes(rootNodeRef, "/app:company_home/cm:Commenty", null, namespaceService, false);
|
results = searchService.selectNodes(rootNodeRef, "/app:company_home/cm:Commenty", null, namespaceService, false);
|
||||||
if (results.size() > 0)
|
if (results.size() > 0)
|
||||||
@@ -77,6 +99,8 @@ public class CommentsApiTest extends BaseWebScriptTest
|
|||||||
versionService.ensureVersioningEnabled(nodeRef, null);
|
versionService.ensureVersioningEnabled(nodeRef, null);
|
||||||
nodeService.setProperty(nodeRef, ContentModel.PROP_AUTO_VERSION_PROPS, true);
|
nodeService.setProperty(nodeRef, ContentModel.PROP_AUTO_VERSION_PROPS, true);
|
||||||
|
|
||||||
|
createUser(USER_TEST);
|
||||||
|
|
||||||
txn.commit();
|
txn.commit();
|
||||||
|
|
||||||
AuthenticationUtil.clearCurrentSecurityContext();
|
AuthenticationUtil.clearCurrentSecurityContext();
|
||||||
@@ -89,9 +113,22 @@ public class CommentsApiTest extends BaseWebScriptTest
|
|||||||
protected void tearDown() throws Exception
|
protected void tearDown() throws Exception
|
||||||
{
|
{
|
||||||
super.tearDown();
|
super.tearDown();
|
||||||
|
|
||||||
|
// admin user required to delete user
|
||||||
|
authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName());
|
||||||
|
|
||||||
|
// delete the discussions users
|
||||||
|
if(personService.personExists(USER_TEST))
|
||||||
|
{
|
||||||
|
personService.deletePerson(USER_TEST);
|
||||||
|
}
|
||||||
|
if (authenticationService.authenticationExists(USER_TEST))
|
||||||
|
{
|
||||||
|
authenticationService.deleteAuthentication(USER_TEST);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addComment(NodeRef nodeRef) throws Exception
|
private void addComment(NodeRef nodeRef, String user, int status) throws Exception
|
||||||
{
|
{
|
||||||
Response response = null;
|
Response response = null;
|
||||||
|
|
||||||
@@ -99,15 +136,15 @@ public class CommentsApiTest extends BaseWebScriptTest
|
|||||||
txn.begin();
|
txn.begin();
|
||||||
|
|
||||||
// Not allowed if you're not an admin
|
// Not allowed if you're not an admin
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
AuthenticationUtil.setFullyAuthenticatedUser(user);
|
||||||
|
|
||||||
StringBuilder body = new StringBuilder("{");
|
StringBuilder body = new StringBuilder("{");
|
||||||
body.append("'title' : 'Test Title', ");
|
body.append("'title' : 'Test Title', ");
|
||||||
body.append("'content' : 'Test Comment'");
|
body.append("'content' : 'Test Comment'");
|
||||||
body.append("}");
|
body.append("}");
|
||||||
|
|
||||||
response = sendRequest(new PostRequest(MessageFormat.format(URL_POST_COMMENT, new Object[] {nodeRef.getStoreRef().getProtocol(), nodeRef.getStoreRef().getIdentifier(), nodeRef.getId()}), body.toString(), JSON), Status.STATUS_OK);
|
response = sendRequest(new PostRequest(MessageFormat.format(URL_POST_COMMENT, new Object[] {nodeRef.getStoreRef().getProtocol(), nodeRef.getStoreRef().getIdentifier(), nodeRef.getId()}), body.toString(), JSON), status);
|
||||||
assertEquals(Status.STATUS_OK, response.getStatus());
|
assertEquals(status, response.getStatus());
|
||||||
|
|
||||||
txn.commit();
|
txn.commit();
|
||||||
}
|
}
|
||||||
@@ -123,8 +160,61 @@ public class CommentsApiTest extends BaseWebScriptTest
|
|||||||
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
||||||
|
|
||||||
String versionBefore = getCurrentVersion(nodeRef);
|
String versionBefore = getCurrentVersion(nodeRef);
|
||||||
addComment(nodeRef);
|
addComment(nodeRef, AuthenticationUtil.getAdminUserName(), 200);
|
||||||
String versionAfter = getCurrentVersion(nodeRef);
|
String versionAfter = getCurrentVersion(nodeRef);
|
||||||
assertEquals(versionBefore, versionAfter);
|
assertEquals(versionBefore, versionAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testCommentPermissions() throws Exception
|
||||||
|
{
|
||||||
|
authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName());
|
||||||
|
UserTransaction txn = transactionService.getUserTransaction();
|
||||||
|
txn.begin();
|
||||||
|
|
||||||
|
NodeRef contentForUserContributor = fileFolderService.create(companyHomeNodeRef, "CommentyContributor" + System.currentTimeMillis(), ContentModel.TYPE_CONTENT).getNodeRef();
|
||||||
|
permissionService.setPermission(new SimplePermissionEntry(contentForUserContributor, getPermission(PermissionService.CONTRIBUTOR), USER_TEST, AccessStatus.ALLOWED));
|
||||||
|
|
||||||
|
NodeRef contentForUserConsumer = fileFolderService.create(companyHomeNodeRef, "CommentyConsumer" + System.currentTimeMillis(), ContentModel.TYPE_CONTENT).getNodeRef();
|
||||||
|
permissionService.setPermission(new SimplePermissionEntry(contentForUserConsumer, getPermission(PermissionService.CONSUMER), USER_TEST, AccessStatus.ALLOWED));
|
||||||
|
|
||||||
|
//Contributor should be able to add comments
|
||||||
|
addComment(contentForUserContributor, USER_TEST, 200);
|
||||||
|
//Consumer shouldn't be able to add comments see MNT-9883
|
||||||
|
addComment(contentForUserConsumer, USER_TEST, 500);
|
||||||
|
|
||||||
|
nodeService.deleteNode(contentForUserContributor);
|
||||||
|
nodeService.deleteNode(contentForUserConsumer);
|
||||||
|
|
||||||
|
txn.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void createUser(String userName)
|
||||||
|
{
|
||||||
|
// if user with given user name doesn't already exist then create user
|
||||||
|
if (!authenticationService.authenticationExists(userName))
|
||||||
|
{
|
||||||
|
// create user
|
||||||
|
authenticationService.createAuthentication(userName, "password".toCharArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!personService.personExists(userName))
|
||||||
|
{
|
||||||
|
// create person properties
|
||||||
|
PropertyMap personProps = new PropertyMap();
|
||||||
|
personProps.put(ContentModel.PROP_USERNAME, userName);
|
||||||
|
personProps.put(ContentModel.PROP_FIRSTNAME, "FirstNameTest");
|
||||||
|
personProps.put(ContentModel.PROP_LASTNAME, "LastNameTest");
|
||||||
|
personProps.put(ContentModel.PROP_EMAIL, "FirstNameTest.LastNameTest@test.com");
|
||||||
|
personProps.put(ContentModel.PROP_JOBTITLE, "JobTitleTest");
|
||||||
|
|
||||||
|
// create person node for user
|
||||||
|
personService.createPerson(personProps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private PermissionReference getPermission(String permission)
|
||||||
|
{
|
||||||
|
return permissionModelDAO.getPermissionReference(null, permission);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user