diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/audit/AuditEntry.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/audit/AuditEntry.java new file mode 100644 index 0000000000..e09d7d71f3 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/audit/AuditEntry.java @@ -0,0 +1,85 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2018 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.audit; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import org.alfresco.utility.model.TestModel; + +@Builder +@Data +@EqualsAndHashCode (callSuper = true) +@NoArgsConstructor +@AllArgsConstructor +@JsonIgnoreProperties (ignoreUnknown = true) +public class AuditEntry extends TestModel +{ + @JsonProperty (required = true) + private String nodeName; + + @JsonProperty (required = true) + private List changedValues; + + @JsonProperty (required = true) + private String identifier; + + @JsonProperty (required = true) + private String path; + + @JsonProperty (required = true) + private String nodeRef; + + @JsonProperty (required = true) + private String fullName; + + @JsonProperty + private String createPerson; + + @JsonProperty (required = true) + private String userName; + + @JsonProperty (required = true) + private String userRole; + + @JsonProperty (required = true) + private String nodeType; + + @JsonProperty (required = true) + private String event; + + @JsonProperty (required = true) + private String timestamp; + +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/audit/AuditEvents.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/audit/AuditEvents.java new file mode 100644 index 0000000000..3e305085a2 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/audit/AuditEvents.java @@ -0,0 +1,50 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2018 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.audit; + +/** + * Enumerates the list of events audited + * @author Rodica Sutu + * @since 2.7 + * + */ +public enum AuditEvents +{ + CREATE_PERSON("Create Person","Create User"), + DELETE_PERSON("Delete Person","Delete User"); + /** event audited */ + public final String event; + + /** display name for the event audited */ + public final String eventDisplayName; + + AuditEvents(String event, String displayName) + { + this.event = event; + this.eventDisplayName = displayName; + } +} \ No newline at end of file diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/util/PojoUtility.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/util/PojoUtility.java index 8ae2c8bd40..344947d363 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/util/PojoUtility.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/util/PojoUtility.java @@ -28,9 +28,18 @@ package org.alfresco.rest.rm.community.util; import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryObject; +import java.io.IOException; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.type.CollectionType; + +import org.json.JSONArray; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Utility class for creating the json object @@ -40,6 +49,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; */ public class PojoUtility { + /** + * Logger for the class. + */ + private static final Logger LOGGER = LoggerFactory.getLogger(PojoUtility.class); + /** * see {@link #toJson(Object, Class, Class)} */ @@ -85,4 +99,54 @@ public class PojoUtility return error.toString(); } } + + /** + * Converting json to object + * + * @param json The json object to convert + * @param classz Class (or interface) whose annotations to effectively override + * @return The converted java object + * @throws JsonProcessingException Throws exceptions if the given object doesn't match to the POJO class model + */ + public static T jsonToObject(JSONObject json, Class classz) + { + mandatoryObject("model", classz); + mandatoryObject("jsonObject", json); + ObjectMapper mapper = new ObjectMapper(); + T obj = null; + try + { + obj = mapper.readValue(json.toString(), classz); + } + catch (IOException e) + { + LOGGER.error("Unable to convert the json into a java object.", e.toString()); + } + + return (T) obj; + } + + public static List jsonToObject(JSONArray json, Class classz) + { + + mandatoryObject("model", classz); + mandatoryObject("jsonObject", json); + + ObjectMapper mapper = new ObjectMapper(); + + CollectionType collectionType = mapper.getTypeFactory().constructCollectionType(List.class, classz); + List asList = null; + try + { + asList = mapper.readValue(json.toString(), collectionType); + } + catch (IOException e) + { + LOGGER.error("Unable to convert the json array into a java collection.", e.toString()); + } + + + return asList; + } + } diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/RMAuditAPI.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/RMAuditAPI.java new file mode 100644 index 0000000000..e2f54a12fb --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/RMAuditAPI.java @@ -0,0 +1,106 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2018 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.v0; + +import static org.testng.Assert.assertTrue; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.text.MessageFormat; +import java.util.List; + +import org.alfresco.rest.core.v0.BaseAPI; +import org.alfresco.rest.rm.community.model.audit.AuditEntry; +import org.alfresco.rest.rm.community.util.PojoUtility; +import org.json.JSONArray; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * The v0 REST API for copy-to (which supports multi-item copy). + * + * @author Tom Page + * @since 2.6 + */ +@Component +public class RMAuditAPI extends BaseAPI +{ + /** Logger for the class. */ + private static final Logger LOGGER = LoggerFactory.getLogger(RMAuditAPI.class); + /** The URI for the audit API. */ + /** + * The URI for the copy-to API. + */ + private static final String RM_AUDIT_API = "{0}rma/admin/rmauditlog"; + private static final String RM_AUDIT_LOG_API = RM_AUDIT_API + "?{1}"; + + /** + * Returns a list of audit entries audit of Records Management events. . + * + * @param user The username of the user to use. + * @param password The password of the user. + * @param size Maximum number of log entries to return + * @param event Only return log entries matching this event + * @return return the A + */ + public List getRMAuditLog(String user, String password, final int size, final String event) + { + String parameters = null; + try + { + parameters = "size=" + size + (event != null ? "&event=" + URLEncoder.encode(event, "UTF-8"): null ); + } + catch (UnsupportedEncodingException e) + { + LOGGER.error("Unable to encode the event name" + e.getMessage()); + } + JSONArray auditEntries = doGetRequest(user, password, + MessageFormat.format(RM_AUDIT_LOG_API,"{0}", parameters)).getJSONObject("data").getJSONArray("entries"); + + return PojoUtility.jsonToObject(auditEntries, AuditEntry.class); + } + + /** + * Clear the list of audit entries audit of Records Management events. . + * + * @param username The username of the user to use. + * @param password The password of the user. + * @throws AssertionError If the API call didn't return a 200 response. + */ + public void clearAuditLog(String username, String password) + { + JSONObject deleteStatus = doDeleteRequest(username, password, RM_AUDIT_API); + + assertTrue(deleteStatus != null + //audit clear and audit login returned + && getRMAuditLog(username, password, 100, null).size() == 2); + } + + +} diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/audit/AuditUserEventsTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/audit/AuditUserEventsTests.java new file mode 100644 index 0000000000..0636c36606 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/audit/AuditUserEventsTests.java @@ -0,0 +1,97 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2018 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.audit; + +import static org.alfresco.rest.rm.community.model.audit.AuditEvents.CREATE_PERSON; +import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.List; + +import org.alfresco.rest.rm.community.base.BaseRMRestTest; +import org.alfresco.rest.rm.community.model.audit.AuditEntry; +import org.alfresco.rest.v0.RMAuditAPI; +import org.alfresco.test.AlfrescoTest; +import org.alfresco.utility.model.UserModel; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * This class contains the tests that check the user events are audited + * + * @author Rodica Sutu + * @since 2.7 + */ +public class AuditUserEventsTests extends BaseRMRestTest +{ + private final String PREFIX = generateTestPrefix(AuditUserEventsTests.class); + + private UserModel createUser; + @Autowired + private RMAuditAPI rmAuditAPI; + + /** + * Given I have created a new user + * When I view the RM audit + * Then there is an entry showing that I created a user + * + * @throws Exception + */ + @Test + @AlfrescoTest(jira = "RM-6223") + public void createUserEventIsAudited() throws Exception + { + String userName = "auditCreateUser" + PREFIX; + + createUser = getDataUser().createUser(userName); + List auditEntries = rmAuditAPI.getRMAuditLog(getAdminUser().getPassword(), + getAdminUser().getPassword(), 100, CREATE_PERSON.event); + + assertTrue("The list of events is not filtered by " + CREATE_PERSON.event, + auditEntries.stream().allMatch(auditEntry -> auditEntry.getEvent().equals(CREATE_PERSON.eventDisplayName))); + + assertTrue("The username value for the user created is not audited.", + auditEntries.stream().filter(auditEntry -> auditEntry.getEvent().equals(CREATE_PERSON.eventDisplayName)) + .allMatch(auditEntry -> auditEntry.getNodeName().equals(userName))); + } + + @BeforeClass (alwaysRun = true) + public void cleanAuditLogs() + { + //clean audit logs + rmAuditAPI.clearAuditLog(getAdminUser().getPassword(), getAdminUser().getPassword()); + } + + @AfterClass (alwaysRun = true) + public void cleanUp() + { + //delete the created user + getDataUser().deleteUser(createUser); + } +}