From 2764802bcadee68e88023460917994a334bb6d7a Mon Sep 17 00:00:00 2001 From: Kristijan Conkas Date: Thu, 22 Dec 2016 16:55:55 +0000 Subject: [PATCH] RM-4426: Tests for user without delete capability. --- .../model/user/UserCapabilities.java | 40 +++++++++++ .../rest/rm/community/requests/RMUserAPI.java | 7 -- .../rest/rm/community/base/BaseRestTest.java | 56 +++++++++++++++ .../fileplancomponents/DeleteRecordTests.java | 68 ++++++++++++++++++- 4 files changed, 163 insertions(+), 8 deletions(-) create mode 100644 rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/user/UserCapabilities.java diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/user/UserCapabilities.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/user/UserCapabilities.java new file mode 100644 index 0000000000..fe9aa1e97d --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/user/UserCapabilities.java @@ -0,0 +1,40 @@ +/* + * #%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 . + * #L% + */ +package org.alfresco.rest.rm.community.model.user; + +/** + * Constants for RM user capabilities + * + * @author Kristijan Conkas + * @since 2.6 + */ +public class UserCapabilities +{ + public static final String CAPABILITY_FILING = "Filing"; + public static final String CAPABILITY_READ_RECORDS = "ReadRecords"; + public static final String CAPABILITY_FILE_RECORDS = "FileRecords"; +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/RMUserAPI.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/RMUserAPI.java index 7cce255240..ec5e0e6d9a 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/RMUserAPI.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/RMUserAPI.java @@ -34,7 +34,6 @@ import com.jayway.restassured.specification.RequestSpecification; import org.alfresco.dataprep.AlfrescoHttpClient; import org.alfresco.dataprep.AlfrescoHttpClientFactory; -import org.alfresco.dataprep.UserService; import org.alfresco.rest.core.RestAPI; import org.alfresco.utility.data.DataUser; import org.springframework.beans.factory.annotation.Autowired; @@ -54,12 +53,6 @@ import org.springframework.stereotype.Component; @Scope (value = "prototype") public class RMUserAPI extends RestAPI { - @Autowired - private RMSiteAPI rmSiteAPI; - - @Autowired - private UserService userService; - @Autowired private DataUser dataUser; diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRestTest.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRestTest.java index 1bd23e434c..02bf6380b8 100644 --- a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRestTest.java +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRestTest.java @@ -28,6 +28,8 @@ package org.alfresco.rest.rm.community.base; import static java.lang.Integer.parseInt; +import static com.jayway.restassured.RestAssured.given; + import static org.alfresco.rest.rm.community.base.TestData.CATEGORY_TITLE; import static org.alfresco.rest.rm.community.base.TestData.FOLDER_TITLE; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS; @@ -37,11 +39,19 @@ import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanCo import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_RECORD_FOLDER_TYPE; import static org.alfresco.rest.rm.community.model.site.RMSiteCompliance.STANDARD; import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric; +import static org.jglue.fluentjson.JsonBuilderFactory.buildObject; import static org.springframework.http.HttpStatus.CREATED; import static org.springframework.http.HttpStatus.OK; +import com.google.gson.JsonObject; import com.jayway.restassured.RestAssured; +import com.jayway.restassured.builder.RequestSpecBuilder; +import com.jayway.restassured.http.ContentType; +import com.jayway.restassured.response.Response; +import com.jayway.restassured.specification.RequestSpecification; +import org.alfresco.dataprep.AlfrescoHttpClient; +import org.alfresco.dataprep.AlfrescoHttpClientFactory; import org.alfresco.rest.RestTest; import org.alfresco.rest.core.RestWrapper; import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent; @@ -96,6 +106,9 @@ public class BaseRestTest extends RestTest @Autowired public FilePlanComponentAPI filePlanComponentAPI; + @Autowired + private AlfrescoHttpClientFactory alfrescoHttpClientFactory; + // Constants public static final String RM_ID = "rm"; public static final String RM_TITLE = "Records Management"; @@ -268,4 +281,47 @@ public class BaseRestTest extends RestTest filePlanComponentAPI.usingRestWrapper().authenticateUser(user); return filePlanComponentAPI.getFilePlanComponent(componentId); } + + /** + * Helper method to add permission on a component to user + * @param component {@link FilePlanComponent} on which permission should be given + * @param user {@link UserModel} for a user to be granted permission + * @param permission permission to be granted (e.g. "Filing") + */ + // FIXME: As of December 2016 there is no v1-style API for managing RM permissions. + // Until such APIs have become available, this method is just a proxy to an "old-style" + // API call. + public void addUserPermission(FilePlanComponent component, UserModel user, String permission) + { + // get an "old-style" REST API client + AlfrescoHttpClient client = alfrescoHttpClientFactory.getObject(); + + JsonObject bodyJson = buildObject() + .addArray("permissions") + .addObject() + .add("authority", user.getUsername()) + .add("role", permission) + .end() + .getJson(); + + // override v1 baseURI and basePath + RequestSpecification spec = new RequestSpecBuilder() + .setBaseUri(client.getApiUrl()) + .setBasePath("/") + .build(); + + // execute an "old-style" API call + Response response = given() + .spec(spec) + .auth().basic(dataUser.getAdminUser().getUsername(), dataUser.getAdminUser().getPassword()) + .contentType(ContentType.JSON) + .body(bodyJson.toString()) + .pathParam("nodeId", component.getId()) + .log().all() + .when() + .post("/node/workspace/SpacesStore/{nodeId}/rmpermissions") + .prettyPeek() + .andReturn(); + filePlanComponentAPI.usingRestWrapper().setStatusCode(Integer.toString(response.getStatusCode())); + } } \ No newline at end of file diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/DeleteRecordTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/DeleteRecordTests.java index cc66203fc2..92b91b49c6 100644 --- a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/DeleteRecordTests.java +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/DeleteRecordTests.java @@ -26,6 +26,7 @@ */ package org.alfresco.rest.rm.community.fileplancomponents; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.CONTENT_TYPE; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.NON_ELECTRONIC_RECORD_TYPE; @@ -38,6 +39,7 @@ import static org.springframework.http.HttpStatus.OK; import org.alfresco.rest.rm.community.base.BaseRestTest; import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent; +import org.alfresco.rest.rm.community.model.user.UserCapabilities; import org.alfresco.rest.rm.community.model.user.UserRoles; import org.alfresco.rest.rm.community.requests.FilePlanComponentAPI; import org.alfresco.rest.rm.community.requests.RMSiteAPI; @@ -160,7 +162,8 @@ public class DeleteRecordTests extends BaseRestTest ( description = "User without write permissions can't delete a record" ) - public void userWithoutDeletePermissionsCantDeleteRecord() throws Exception + @AlfrescoTest(jira="RM-4363") + public void userWithoutWritePermissionsCantDeleteRecord() throws Exception { filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); rmSiteAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); @@ -193,6 +196,69 @@ public class DeleteRecordTests extends BaseRestTest filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(FORBIDDEN); } + /** + *
+     * Given a record
+     * And that I don't have the "Delete Record" capability
+     * When I try to delete the record
+     * Then nothing happens
+     * And error gets reported
+     * 
+ * + * @param container + * @throws Exception + */ + @Test + ( + description = "User without delete records capability can't delete a record" + ) + @AlfrescoTest(jira="RM-4363") + public void userWithoutDeleteRecordsCapabilityCantDeleteRecord() throws Exception + { + filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + rmSiteAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + + // create test user and add it with collab. privileges + UserModel deleteUser = dataUser.createRandomTestUser("delnoperm"); + deleteUser.setUserRole(UserRole.SiteCollaborator); + dataUser.addUserToSite(deleteUser, new SiteModel(rmSiteAPI.getSite().getId()), UserRole.SiteCollaborator); + logger.info("test user: " + deleteUser.getUsername()); + + // add RM role to user, RM Power User doesn't have the Delete Record capabilities + rmUserAPI.assignRoleToUser(deleteUser.getUsername(), UserRoles.ROLE_RM_POWER_USER); + rmUserAPI.usingRestWrapper().assertStatusCodeIs(OK); + + // create random folder + FilePlanComponent randomFolder = createCategoryFolderInFilePlan(dataUser.getAdminUser(), FILE_PLAN_ALIAS.toString()); + logger.info("random folder:" + randomFolder.getName()); + + // grant deleteUser Filing privileges on randomFolder category, this will be + // inherited to randomFolder + addUserPermission(filePlanComponentAPI.getFilePlanComponent(randomFolder.getParentId()), + deleteUser, UserCapabilities.CAPABILITY_FILING); + + // create a non-electronic record in randomFolder + FilePlanComponent record = FilePlanComponent.builder() + .name("Record " + getRandomAlphanumeric()) + .nodeType(NON_ELECTRONIC_RECORD_TYPE.toString()) + .build(); + FilePlanComponent newRecord = filePlanComponentAPI.createFilePlanComponent( + record, + randomFolder.getId()); + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(CREATED); + + // log in as deleteUser + filePlanComponentAPI.usingRestWrapper().authenticateUser(deleteUser); + + // verify the user can see the newRecord + filePlanComponentAPI.getFilePlanComponent(newRecord.getId()); + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(OK); + + // try to delete newRecord + filePlanComponentAPI.deleteFilePlanComponent(newRecord.getId()); + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(FORBIDDEN); + } + /** * Utility method to delete a record and verify successful deletion * @param record