/*
* #%L
* Alfresco Records Management Module
* %%
* 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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.module.org_alfresco_module_rm.test.legacy.webscript;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashSet;
import java.util.Set;
import org.alfresco.module.org_alfresco_module_rm.capability.Capability;
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService;
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMWebScriptTestCase;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.util.GUID;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.TestWebScriptServer.DeleteRequest;
import org.springframework.extensions.webscripts.TestWebScriptServer.PostRequest;
import org.springframework.extensions.webscripts.TestWebScriptServer.Response;
/**
* REST API Tests for adding/removing users/groups to/from a role
*
* @author Tuna Aksoy
* @since 2.1
*/
public class RmAuthoritiesRestApiTest extends BaseRMWebScriptTestCase
{
/** URL for the REST APIs */
private static final String RM_CHILDREN_URL = "/api/rm/%s/roles/%s/authorities/%s";
/** Constant for the content type */
private static final String APPLICATION_JSON = "application/json";
/** Constant for users and groups */
private static final String USER_WITH_CAPABILITY = GUID.generate();
private static final String USER_WITHOUT_CAPABILITY = GUID.generate();
private static final String ROLE_INCLUDING_CAPABILITY = GUID.generate();
private static final String ROLE_NOT_INCLUDING_CAPABILITY = GUID.generate();
private static final String USER_TO_ADD_TO_ROLE = GUID.generate();
private static final String GROUP_TO_ADD_TO_ROLE = GUID.generate();
/**
* @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMWebScriptTestCase#setupTestData()
*/
@Override
protected void setupTestData()
{
super.setupTestData();
retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Object>()
{
@Override
public Object execute() throws Throwable
{
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getSystemUserName());
// Create test user WITH required capability
createUser(USER_WITH_CAPABILITY);
// Create test role
Set<Capability> capabilities = new HashSet<Capability>(2);
capabilities.add(capabilityService.getCapability(RMPermissionModel.VIEW_RECORDS));
capabilities.add(capabilityService.getCapability(RMPermissionModel.MANAGE_ACCESS_CONTROLS));
filePlanRoleService.createRole(filePlan, ROLE_INCLUDING_CAPABILITY, ROLE_INCLUDING_CAPABILITY, capabilities);
// Add user to the role
filePlanRoleService.assignRoleToAuthority(filePlan, ROLE_INCLUDING_CAPABILITY, USER_WITH_CAPABILITY);
// Create test user WITHOUT required capability
createUser(USER_WITHOUT_CAPABILITY);
// Create test role
filePlanRoleService.createRole(filePlan, ROLE_NOT_INCLUDING_CAPABILITY, ROLE_NOT_INCLUDING_CAPABILITY, new HashSet<Capability>(1));
// Add user to the role
filePlanRoleService.assignRoleToAuthority(filePlan, ROLE_NOT_INCLUDING_CAPABILITY, USER_WITHOUT_CAPABILITY);
// Create a test user to add to role
createUser(USER_TO_ADD_TO_ROLE);
// Create a group to add to role
createGroup(GROUP_TO_ADD_TO_ROLE);
return null;
}
});
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMWebScriptTestCase#tearDownImpl()
*/
@Override
protected void tearDownImpl()
{
super.tearDownImpl();
// Delete test user WITH required capability
deleteUser(USER_WITH_CAPABILITY);
// Delete test role
filePlanRoleService.deleteRole(filePlan, ROLE_INCLUDING_CAPABILITY);
// Delete test user WITHOUT required capability
deleteUser(USER_WITHOUT_CAPABILITY);
// Add user to the role
filePlanRoleService.deleteRole(filePlan, ROLE_NOT_INCLUDING_CAPABILITY);
// Delete the user which was added to the role
deleteUser(getTestUserName());
// Delete the group which was added to the role
deleteGroup(getTestGroupName());
}
/**
* Test the REST API to add/remove a user to/from a role
*
* @throws IOException
* @throws JSONException
*/
public void testRmAddRemoveUser() throws IOException, JSONException
{
// Do the positive test with a user with the needed capabilities
AuthenticationUtil.setFullyAuthenticatedUser(USER_WITH_CAPABILITY);
// Get the user name
String userName = getTestUserName();
// Check if the user is already assigned to the role
assertFalse(getUsersAssignedToRole().contains(userName));
// Format url, send the request and check the content
String url = getFormattedUrlString(userName);
checkContent(postRequestSuccess(url));
// The user should be added to the role
assertTrue(getUsersAssignedToRole().contains(userName));
// Remove the user from the role and check the content
checkContent(deleteRequestSuccess(url));
// The user should be removed from the role
assertFalse(getUsersAssignedToRole().contains(userName));
// Do the negative test with a user without any capabilities
AuthenticationUtil.setFullyAuthenticatedUser(USER_WITHOUT_CAPABILITY);
// Send a request. The expectation is an internal server error
postRequestFailure(url);
}
/**
* Test the REST API to add/remove a group to/from a role
*
* @throws IOException
* @throws JSONException
*/
public void testRmAddRemoveGroup() throws IOException, JSONException
{
// Do the positive test with a user with the needed capabilities
AuthenticationUtil.setFullyAuthenticatedUser(USER_WITH_CAPABILITY);
// Get the group name
String groupName = getTestGroupName();
// Check if the group is already assigned to the role
assertFalse(getGroupsAssignedToRole().contains(groupName));
// Format url, send the request and check the content
String url = getFormattedUrlString(groupName);
checkContent(postRequestSuccess(url));
// The group should be added to the role
assertTrue(getGroupsAssignedToRole().contains(groupName));
// Remove the group from the role and check the content
checkContent(deleteRequestSuccess(url));
// The user should be removed from the role
assertFalse(getGroupsAssignedToRole().contains(groupName));
// Do the negative test with a user without any capabilities
AuthenticationUtil.setFullyAuthenticatedUser(USER_WITHOUT_CAPABILITY);
// Send a request. The expectation is an internal server error
deleteRequestFailure(url);
}
/**
* Util method to get the user name which will be added/removed to/from the role
*
* @return Returns the user name which will be added/removed to/from the role
*/
private String getTestUserName()
{
return authorityService.getName(AuthorityType.USER, USER_TO_ADD_TO_ROLE);
}
/**
* Util method to get the group name which will be added/removed to/from the role
*
* @return Returns the user group which will be added/removed to/from the role
*/
private String getTestGroupName()
{
return authorityService.getName(AuthorityType.GROUP, GROUP_TO_ADD_TO_ROLE);
}
/**
* Util method to get a set of groups assigned to a role
*
* @return Returns a set of groups assigned to a role
*/
private Set<String> getGroupsAssignedToRole()
{
return filePlanRoleService.getGroupsAssignedToRole(filePlan, FilePlanRoleService.ROLE_SECURITY_OFFICER);
}
/**
* Util method to get a set of users assigned to a role
*
* @return Returns a set of users assigned to a role
*/
private Set<String> getUsersAssignedToRole()
{
return filePlanRoleService.getUsersAssignedToRole(filePlan, FilePlanRoleService.ROLE_SECURITY_OFFICER);
}
/**
* Util method to get a formatted nodeRef string
*
* @return Returns a formatted nodeRef string
*/
private String getFormattedFilePlanString()
{
StoreRef storeRef = filePlan.getStoreRef();
String storeType = storeRef.getProtocol();
String storeId = storeRef.getIdentifier();
String id = filePlan.getId();
StringBuffer sb = new StringBuffer(32);
sb.append(storeType);
sb.append("/");
sb.append(storeId);
sb.append("/");
sb.append(id);
return sb.toString();
}
/**
* Util method to get a formatted url string
*
* @param authorityName The name of the authority which should be added/removed to/from a role
* @return Returns a formatted url string
*/
private String getFormattedUrlString(String authorityName)
{
return String.format(RM_CHILDREN_URL, getFormattedFilePlanString(), FilePlanRoleService.ROLE_SECURITY_OFFICER, authorityName);
}
/**
* Util method to send a post request. The expected status is success.
*
* @param url The url which should be used to make the post request
* @return Returns the response from the server
* @throws UnsupportedEncodingException
* @throws IOException
*/
private Response postRequestSuccess(String url) throws UnsupportedEncodingException, IOException
{
return sendRequest(new PostRequest(url, new JSONObject().toString(), APPLICATION_JSON), Status.STATUS_OK);
}
/**
* Util method to send a post request. The expected status is an internal server error.
*
* @param url The url which should be used to make the post request
* @return Returns the response from the server
* @throws UnsupportedEncodingException
* @throws IOException
*/
private Response postRequestFailure(String url) throws UnsupportedEncodingException, IOException
{
return sendRequest(new PostRequest(url, new JSONObject().toString(), APPLICATION_JSON), Status.STATUS_INTERNAL_SERVER_ERROR);
}
/**
* Util method to send a delete request. The expected status is success.
*
* @param url The url which should be used to make the delete request
* @return Returns the response from the server
* @throws IOException
*/
private Response deleteRequestSuccess(String url) throws IOException
{
return sendRequest(new DeleteRequest(url), Status.STATUS_OK);
}
/**
* Util method to send a delete request. The expected status is an internal server error.
*
* @param url The url which should be used to make the delete request
* @return Returns the response from the server
* @throws IOException
*/
private Response deleteRequestFailure(String url) throws IOException
{
return sendRequest(new DeleteRequest(url), Status.STATUS_INTERNAL_SERVER_ERROR);
}
/**
* Util method to check the server response
*
* @param response The server response
* @throws UnsupportedEncodingException
*/
private void checkContent(Response response) throws UnsupportedEncodingException
{
String contentAsString = response.getContentAsString();
assertNotNull(contentAsString);
assertTrue(contentAsString.contains("{}"));
}
}