Compare commits

..

24 Commits

Author SHA1 Message Date
alfresco-build
99aaee239e [maven-release-plugin] prepare release V3.2.0.4 2020-08-19 13:10:47 +01:00
alfresco-build
fbdc279994 [maven-release-plugin] prepare for next development iteration 2020-08-19 11:32:54 +01:00
alfresco-build
7b396dc652 [maven-release-plugin] prepare release V3.2.0.3 2020-08-19 11:32:43 +01:00
alfresco-build
5b080cf308 [maven-release-plugin] prepare for next development iteration 2020-08-14 12:04:35 +01:00
alfresco-build
c6a9ec43f5 [maven-release-plugin] prepare release V3.2.0.2 2020-08-14 12:04:24 +01:00
evasques
0ea0565909 Merge pull request #1182 from Alfresco/hotfix-3.2/MNT-21585_fix_ipr_group_match
MNT-21585 - Having EVERYONE in original ACL causes IPR duplication (#…
2020-08-10 11:10:21 +01:00
evasques
ff81afe125 MNT-21585 - Having EVERYONE in original ACL causes IPR duplication (#1144)
* MNT-21585 - Having EVERYONE in original authorities causes IPR duplication

* Update License Headers

* prevent NPE when authorities is null and refactored findIPRGroup method
2020-07-29 13:21:33 +01:00
Claudia Agache
2a014eefe0 Merge remote-tracking branch 'remotes/origin/release/V3.1' into merge-3.2/APPS-235_SetupEnv_no
# Conflicts:
#	.travis.yml
2020-07-15 16:49:27 +03:00
rodicasutu
4c9fe378c6 Merge remote-tracking branch 'remotes/origin/release/V3.1' into merge-3.2/APPS-230_BuildAGSOnTravis
# Conflicts:
#	pom.xml

# Conflicts:
#	.travis.settings.xml
#	.travis.yml
2020-07-15 09:19:38 +03:00
Claudia Agache
6d22541437 Change SCM URLs in order to switch to SSH authentication with 2FA for Github
(cherry picked from commit 53f26b5793)
2020-06-09 08:53:33 +01:00
Claudia Agache
06a8df491c RM-7131 Update old gitlab repo links with the new one from github
(cherry picked from commit c3cdd88873)
2020-06-09 08:29:35 +01:00
alfresco-build
5b34dbd24f [maven-release-plugin] prepare for next development iteration 2020-02-26 12:04:24 +00:00
alfresco-build
783dcc7710 [maven-release-plugin] prepare release V3.2.0.1 2020-02-26 12:04:18 +00:00
Rodica Sutu
7604b96b88 Merge branch 'hotfix-3.2/MNT-21292_DownloadsViaPostForRecord' into 'release/V3.2.0.x'
Resolve MNT-21292 "Hotfix 3.2/ downloadsviapostforrecord"

See merge request records-management/records-management!1388
2020-02-24 10:52:15 +00:00
Rodica Sutu
e78f159844 Merge branch 'feature/RM-7012_ActionNameInListOfValuesForAudit' into 'master'
RM-7012

See merge request records-management/records-management!1280

(cherry picked from commit a3450f74cf)
2020-02-21 15:04:35 +02:00
Rodica Sutu
43268debd3 move test DownloadAsZipRecordTest into rm enterprise package as there is no ACS 6.1.1 community equivalent and the issue is not reproducing with ACS community 6.1.2-ga 2020-02-21 11:23:32 +02:00
Rodica Sutu
b2b0121d20 revert unwanted changes 2020-02-20 12:53:54 +02:00
Rodica Sutu
738fce1c37 update the ACS library versions in order to have the changes that cause download post to work 2020-02-20 10:11:22 +02:00
Rodica Sutu
1292cb495b Merge branch 'feature/RM-7006_UpdateToACS611' into 'master'
RM-7006 Update to ACS 6.1.1

Closes RM-7006

See merge request records-management/records-management!1272
2020-02-19 19:56:11 +02:00
Rodica Sutu
098c80bd03 cherry pick
# Conflicts:
#	rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/AssocPolicy.java
#	rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/DownloadAsZipRecordTest.java
2020-02-18 16:32:43 +02:00
Rodica Sutu
49f504ba93 update the assoc policy for the case when the create assoc source node is not a file plan component node 2020-02-18 16:31:20 +02:00
Rodica Sutu
d85d6227ce Merge branch 'hotfix-3.2/MNT-21292_UpdateHeadersCherryPick' into 'release/V3.2.0.x'
Hotfix 3.2/ updateheaderscherrypick"

See merge request records-management/records-management!1386
2020-02-18 14:16:14 +00:00
Sara Aspery
2790244142 Update license headers 2020-02-18 11:10:36 +02:00
Sara Aspery
2d0913df35 Merge branch 'release/V3.1' into release/V3.2 2020-02-18 11:07:45 +02:00
193 changed files with 1697 additions and 6124 deletions

3
.gitignore vendored
View File

@@ -6,7 +6,6 @@
.project
.settings
.history
*.bak
*.eml
*.iml
*.log*
@@ -17,8 +16,6 @@ build.local.properties
dist
explodedDeps
local.properties
rebel.xml
rebel-remote.xml
target
test-output

68
.travis.settings.xml Normal file
View File

@@ -0,0 +1,68 @@
<settings>
<profiles>
<profile>
<id>alfresco-internal</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>alfresco-internal</id>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
<name>Alfresco Internal Repository</name>
<url>https://artifacts.alfresco.com/nexus/content/groups/internal</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>alfresco-internal</id>
<name>Alfresco Internal Repository</name>
<url>https://artifacts.alfresco.com/nexus/content/groups/internal</url>
</pluginRepository>
<pluginRepository>
<id>alfresco-public</id>
<name>Alfresco Public Repository</name>
<url>https://artifacts.alfresco.com/nexus/content/groups/public</url>
</pluginRepository>
<pluginRepository>
<id>alfresco-private</id>
<name>Alfresco Private Repository</name>
<url>https://artifacts.alfresco.com/nexus/content/groups/private</url>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<servers>
<server>
<id>docker.io</id>
<username>${env.DOCKERHUB_USERNAME}</username>
<password>${env.DOCKERHUB_PASSWORD}</password>
</server>
<server>
<id>quay.io</id>
<username>${env.QUAY_USERNAME}</username>
<password>${env.QUAY_PASSWORD}</password>
</server>
<server>
<id>alfresco-internal</id>
<username>${env.MAVEN_USERNAME}</username>
<password>${env.MAVEN_PASSWORD}</password>
</server>
<server>
<id>alfresco-private</id>
<username>${env.MAVEN_USERNAME}</username>
<password>${env.MAVEN_PASSWORD}</password>
</server>
<server>
<id>alfresco-internal-snapshots</id>
<username>${env.MAVEN_USERNAME}</username>
<password>${env.MAVEN_PASSWORD}</password>
</server>
</servers>
</settings>

View File

@@ -1,6 +1,129 @@
import:
- source: travis-env-vars.yml
os: linux
dist: xenial
language: java
jdk:
- openjdk11
sudo: false
install: true
script: travis_wait 35 mvn -B clean verify -Dcommunity -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
services:
- docker
branches:
only:
- /release\/V3.\d+.*/
- /feature-3.\d+\/.*/
- /merge-3.\d+\/.*/
- /hotfix-3.\d+\/.*/
cache:
directories:
- $HOME/.m2
# the cache can grow constantly
before_cache:
- rm -rf $HOME/.m2/repository/org/alfresco/alfresco-governance-services*
before_install:
- "cp .travis.settings.xml $HOME/.m2/settings.xml"
install: skip
stages:
- name: Build AGS
- name: Tests
if: commit_message !~ /\[skip tests\]/
- name: Security Scans
- name: Release
- name: Publish
jobs:
include:
- name: "Build AGS Community"
stage: Build AGS
before_script: source scripts/setUpMavenPhase.sh
script:
- travis_retry travis_wait 120 mvn -B -q clean ${MAVEN_PHASE} -P${BUILD_PROFILE} -Dimage.tag=${IMAGE_TAG} -Dskip.integrationtests=false -Dcommunity -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
- name: "Build AGS Enterprise"
stage: Build AGS
before_script: source scripts/setUpMavenPhase.sh
install:
- travis_retry travis_wait 60 mvn -B -q clean install $MVN_SKIP -f rm-community/pom.xml -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
script:
- travis_retry travis_wait 80 mvn -B -q ${MAVEN_PHASE} -P${BUILD_PROFILE} -Dimage.tag=${IMAGE_TAG} -Dskip.integrationtests=false -f rm-enterprise/pom.xml -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
- name: "Build AGS Benchmark"
stage: Build AGS
before_script: source scripts/setUpMavenPhase.sh
install:
- travis_retry travis_wait 80 mvn -B -q clean install $MVN_SKIP -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
script:
- travis_retry travis_wait 35 mvn -B -q ${MAVEN_PHASE} -Dskip.integrationtests=false -f rm-benchmark/pom.xml -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
- name: "Community Integrations Tests on MySQL"
stage: Tests
script:
- echo "Community Integrations Tests on MySQL"
- name: "Enterprise Integrations Tests on MySQL"
stage: Tests
script:
- echo "Enterprise Integrations Tests on MySQL"
- name: "Community Rest API Tests"
stage: Tests
before_install:
- travis_retry travis_wait 90 mvn -B -q install $MVN_SKIP -PbuildDockerImage -pl :alfresco-governance-services-community-repo -am
install:
- bash scripts/startAlfresco.sh $COMMUNITY_REPO_PATH
- bash scripts/waitForAlfrescoToStart.sh
script:
- echo "Community Rest API Tests"
- name: "Enterprise Rest API Tests"
stage: Tests
before_install:
- travis_retry travis_wait 90 mvn -B -q install $MVN_SKIP -PbuildDockerImage -pl :alfresco-governance-services-enterprise-repo -am
install:
- bash scripts/startAlfresco.sh $ENTERPRISE_REPO_PATH
- bash scripts/waitForAlfrescoToStart.sh
script:
- echo "Enterprise Rest API Tests"
- name: "Community UI Tests ..."
stage: Tests
before_install:
- travis_retry travis_wait 90 mvn -B -q install $MVN_SKIP -PbuildDockerImage -pl :alfresco-governance-services-community-repo,:alfresco-governance-services-community-share -am
install:
- bash scripts/startAlfresco.sh $COMMUNITY_SHARE_PATH
- bash scripts/waitForAlfrescoToStart.sh
script:
- echo "Community UI Tests ..."
- name: "Enterprise UI Tests ..."
stage: Tests
before_install:
- travis_retry travis_wait 90 mvn -B -q install $MVN_SKIP -PbuildDockerImage -pl :alfresco-governance-services-enterprise-repo,:alfresco-governance-services-enterprise-share -am
install:
- bash scripts/startAlfresco.sh $ENTERPRISE_SHARE_PATH
- bash scripts/waitForAlfrescoToStart.sh
script:
- echo "Enterprise UI Tests ..."
- name: "Source Clear Scan (SCA)"
stage: Security Scans
script:
- echo "Source Clear Scan (SCA)"
- name: "Static Analysis (SAST)"
stage: Security Scans
script:
- echo "Static Analysis (SAST)"
- name: "Community Release"
stage: Release
script:
- echo "Community Release"
- name: "Enterprise Release"
stage: Release
script:
- echo "Enterprise Release"
- name: "Copy to S3 Release Bucket"
stage: Publish
script:
- echo "Copy to S3 Release Bucket"

View File

@@ -170,10 +170,3 @@ docker-compose up
> Be aware of the fact that the Share images can not be started independently from Repo
e.g. In order to start an instance of rm-enterprise-repo and rm-enterprise-share, the above command must be run in rm-enterprise-share after the images have been built.
## Start the Docker images with jRebel in remote server mode
If you have a license for jRebel then this can be used from the rm-community-share or rm-enterprise-share directories with:
```
docker-compose -f docker-compose.yml -f jrebel-docker-compose.yml --project-name agsdev up --build --force-recreate
```

26
pom.xml
View File

@@ -4,7 +4,7 @@
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services</artifactId>
<packaging>pom</packaging>
<version>3.3.0.1</version>
<version>3.2.0.4</version>
<name>Alfresco Governance Services</name>
<url>http://www.alfresco.org/</url>
@@ -15,10 +15,10 @@
</organization>
<scm>
<connection>scm:git:https://git.alfresco.com/records-management/records-management.git</connection>
<developerConnection>scm:git:https://git.alfresco.com/records-management/records-management.git</developerConnection>
<url>https://git.alfresco.com/records-management/records-management</url>
<tag>V3.3.0.1</tag>
<connection>scm:git:ssh://git@github.com/Alfresco/governance-services.git</connection>
<developerConnection>scm:git:ssh://git@github.com/Alfresco/governance-services.git</developerConnection>
<url>scm:git:ssh://git@github.com/Alfresco/governance-services.git</url>
<tag>V3.2.0.4</tag>
</scm>
<issueManagement>
@@ -468,6 +468,7 @@
<id>start</id>
<phase>pre-integration-test</phase>
<goals>
<goal>stop</goal>
<goal>start</goal>
</goals>
<configuration>
@@ -531,10 +532,10 @@
<alfresco.db.username>alfresco</alfresco.db.username>
<alfresco.groupId>org.alfresco</alfresco.groupId>
<alfresco.share.artifactId>share</alfresco.share.artifactId>
<alfresco-spring-webscripts.version>7.9</alfresco-spring-webscripts.version>
<api.explorer.version>6.2.0</api.explorer.version>
<alfresco-spring-webscripts.version>7.8</alfresco-spring-webscripts.version>
<api.explorer.version>6.1.0</api.explorer.version>
<!-- Set this here and override it in the community and enterprise modules. -->
<alfresco.min.version>0.0</alfresco.min.version>
<alfresco.version>0.0</alfresco.version>
<skip.integrationtests>true</skip.integrationtests>
<postgres.version>9.4.12</postgres.version>
@@ -559,8 +560,8 @@
<maven.tomcat.port>8080</maven.tomcat.port>
<jackson.version>2.9.9</jackson.version>
<jackson-databind.version>2.9.10.1</jackson-databind.version>
<fabric8.docker.version>0.31.0</fabric8.docker.version>
<jackson-databind.version>2.9.9.3</jackson-databind.version>
<fabric8.docker.version>0.25.0</fabric8.docker.version>
<mockito.version>1.10.19</mockito.version>
<postgresql.version>42.2.6</postgresql.version>
<postgresql.port>5432</postgresql.port>
@@ -592,7 +593,6 @@
<image.registry>quay.io</image.registry>
<javax-jaxb.version>2.3.0</javax-jaxb.version>
<apache-compress.version>1.19</apache-compress.version>
</properties>
<dependencyManagement>
@@ -694,7 +694,7 @@
<regexPropertySettings>
<regexPropertySetting>
<name>ags.module.repo.version.min</name>
<value>${alfresco.min.version}</value>
<value>${alfresco.version}</value>
<regex>(\d+)\.(\d+).*</regex>
<replacement>$1.$2</replacement>
<failIfNoMatch>false</failIfNoMatch>
@@ -1121,7 +1121,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>${apache-compress.version}</version>
<version>1.18</version>
</dependency>
<dependency>
<groupId>org.alfresco.maven.plugin</groupId>

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services</artifactId>
<version>3.3.0.1</version>
<version>3.2.0.4</version>
</parent>
<licenses>

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-automation</artifactId>
<version>3.3.0.1</version>
<version>3.2.0.4</version>
</parent>
<properties>

View File

@@ -103,7 +103,7 @@ public abstract class BaseAPI
*/
protected List<String> getPropertyValues(JSONObject result, String propertyName)
{
ArrayList<String> results = new ArrayList<>();
ArrayList<String> results = new ArrayList<String>();
try
{
JSONArray items = result.getJSONArray("items");
@@ -541,6 +541,7 @@ public abstract class BaseAPI
AlfrescoHttpClient client = alfrescoHttpClientFactory.getObject();
T request = requestType.newInstance();
HttpResponse response = null;
JSONObject responseBody = null;
JSONObject returnValues = null;
@@ -554,7 +555,7 @@ public abstract class BaseAPI
}
LOGGER.info("Sending {} request to {}", requestType.getSimpleName(), requestUrl);
LOGGER.info("Request body: {}", requestParams);
HttpResponse response = client.execute(adminUser, adminPassword, request);
response = client.execute(adminUser, adminPassword, request);
LOGGER.info("Response: {}", response.getStatusLine());
try
@@ -586,13 +587,13 @@ public abstract class BaseAPI
case HttpStatus.SC_UNPROCESSABLE_ENTITY:
if (responseBody != null && responseBody.has(EXCEPTION_KEY))
{
LOGGER.error("Request failed: {}", responseBody.getString(EXCEPTION_KEY));
LOGGER.error("Request failed: " + responseBody.getString(EXCEPTION_KEY));
returnValues = responseBody;
}
break;
default:
LOGGER.error("Request returned unexpected HTTP status {}", response.getStatusLine().getStatusCode());
LOGGER.error("Request returned unexpected HTTP status " + response.getStatusLine().getStatusCode());
break;
}
}

View File

@@ -41,11 +41,7 @@ public enum AuditEvents
DELETE_USER_GROUP("Delete User Group", "Delete User Group"),
ADD_TO_USER_GROUP("Add To User Group", "Add To User Group"),
REMOVE_FROM_USER_GROUP("Remove From User Group", "Remove From User Group"),
LOGIN_UNSUCCESSFUL("Login.Failure", "Login Unsuccessful"),
CREATE_HOLD("Create Hold", "Create Hold"),
DELETE_HOLD("Delete Hold", "Delete Hold"),
ADD_TO_HOLD("Add To Hold", "Add To Hold"),
REMOVE_FROM_HOLD("Remove From Hold", "Remove From Hold");
LOGIN_UNSUCCESSFUL("Login.Failure", "Login Unsuccessful");
/** event audited */
public final String event;

View File

@@ -34,11 +34,6 @@ package org.alfresco.rest.rm.community.model.fileplancomponents;
*/
public class FilePlanComponentAspects
{
/** Private constructor to prevent instantiation. */
private FilePlanComponentAspects()
{
}
// aspect present on completed records
public static final String ASPECTS_COMPLETED_RECORD = "rma:declaredRecord";
@@ -47,10 +42,4 @@ public class FilePlanComponentAspects
// aspect present on vital records
public static final String ASPECTS_VITAL_RECORD = "rma:vitalRecord";
// Frozen aspect
public static final String FROZEN_ASPECT = "rma:frozen";
// recordSearch aspect
public static final String RECORD_SEARCH_ASPECT = "rma:recordSearch";
}

View File

@@ -109,7 +109,7 @@ public class Record extends TestModel implements IRestModel<RestNodeModel>
@Override
public ModelAssertion<RestNodeModel> assertThat()
{
return new ModelAssertion<>(this);
return new ModelAssertion<RestNodeModel>(this);
}
@Override

View File

@@ -53,7 +53,7 @@ import lombok.NoArgsConstructor;
@AllArgsConstructor
public class RecordCategory extends TestModel
{
public static final String DEFAULT_FILE_PLAN_ALIAS = "-filePlan-";
public final static String DEFAULT_FILE_PLAN_ALIAS = "-filePlan-";
/*************************/
/** Mandatory parameters */

View File

@@ -53,7 +53,7 @@ import lombok.NoArgsConstructor;
@AllArgsConstructor
public class RecordCategoryChild extends TestModel
{
public static final String RECORD_FOLDER_NODE_TYPE = "rma:recordFolder";
public final static String RECORD_FOLDER_NODE_TYPE = "rma:recordFolder";
/*************************/
/** Mandatory parameters */

View File

@@ -28,6 +28,7 @@ package org.alfresco.rest.rm.community.requests.gscore.api;
import static org.alfresco.rest.core.RestRequest.simpleRequest;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryString;
import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.springframework.http.HttpMethod.POST;
import org.alfresco.rest.core.RMRestWrapper;

View File

@@ -54,10 +54,6 @@ public class PojoUtility
*/
private static final Logger LOGGER = LoggerFactory.getLogger(PojoUtility.class);
/** Private constructor to prevent instantiation. */
private PojoUtility()
{}
/**
* see {@link #toJson(Object, Class, Class)}
*/
@@ -126,7 +122,7 @@ public class PojoUtility
}
catch (IOException e)
{
LOGGER.error("Unable to convert the json into a java object.", e);
LOGGER.error("Unable to convert the json into a java object.", e.toString());
}
return obj;
@@ -156,7 +152,7 @@ public class PojoUtility
}
catch (IOException e)
{
LOGGER.error("Unable to convert the json array into a java collection.", e);
LOGGER.error("Unable to convert the json array into a java collection.", e.toString());
}

View File

@@ -105,7 +105,7 @@ public class CustomDefinitionsAPI extends BaseAPI
}
catch (JSONException error)
{
LOGGER.error("Unable to get the refId for the custom reference definition {}", customDefinition);
LOGGER.error("Unable to get the refId for the custom reference definition " + customDefinition);
}
}
return null;

View File

@@ -28,6 +28,7 @@ package org.alfresco.rest.v0;
import static org.alfresco.rest.core.v0.APIUtils.convertHTTPResponseToJSON;
import static org.apache.http.HttpStatus.SC_OK;
import static org.testng.AssertJUnit.assertNotNull;
import java.text.MessageFormat;
import java.util.Collections;
@@ -38,7 +39,8 @@ import org.alfresco.rest.core.v0.APIUtils;
import org.alfresco.rest.core.v0.BaseAPI;
import org.alfresco.rest.rm.community.model.hold.HoldEntry;
import org.alfresco.rest.rm.community.util.PojoUtility;
import org.alfresco.utility.model.UserModel;
import org.alfresco.utility.Utility;
import org.apache.chemistry.opencmis.client.api.CmisObject;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.json.JSONArray;
@@ -79,27 +81,18 @@ public class HoldsAPI extends BaseAPI
* @param holdName the hold name
* @param reason hold reason
* @param description hold description
* @return The HTTP response.
* @return The HTTP response (or null if no POST call was needed).
*/
public HttpResponse createHold(String user, String password, String holdName, String reason, String description)
{
return createHold(user, password, holdName, reason, description, SC_OK);
}
/**
* Util method to create a hold
*
* @param user the user creating the hold
* @param password the user's password
* @param holdName the hold name
* @param reason hold reason
* @param description hold description
* @param expectedStatusCode The expected return status code.
* @return The HTTP response or throws AssertionError if the returned status code is not as expected.
*/
public HttpResponse createHold(String user, String password, String holdName, String reason, String description,
int expectedStatusCode)
public HttpResponse createHold(String user, String password,
String holdName, String reason, String description)
{
// if the hold already exists don't try to create it again
final String fullHoldPath = Utility.buildPath(getFilePlanPath(), HOLDS_CONTAINER) + holdName;
final CmisObject hold = getObjectByPath(user, password, fullHoldPath);
if (hold != null)
{
return null;
}
// retrieve the Holds container nodeRef
final String parentNodeRef = getItemNodeRef(user, password, "/" + HOLDS_CONTAINER);
@@ -109,7 +102,11 @@ public class HoldsAPI extends BaseAPI
requestParams.put("prop_cm_description", description);
requestParams.put("prop_rma_holdReason", reason);
return doPostJsonRequest(user, password, expectedStatusCode, requestParams, CREATE_HOLDS_API);
// Make the POST request and throw an assertion error if it fails.
final HttpResponse httpResponse = doPostJsonRequest(user, password, SC_OK, requestParams, CREATE_HOLDS_API);
assertNotNull("Expected object to have been created at " + fullHoldPath,
getObjectByPath(user, password, fullHoldPath));
return httpResponse;
}
/**
@@ -145,36 +142,7 @@ public class HoldsAPI extends BaseAPI
}
/**
* Deletes hold using RM Actions API and expect action to be successful
*
* @param user the user who does the request
* @param holdNodeRef the hold node ref
* @return The HTTP Response or throws AssertionError if the request is not successful.
*/
public HttpResponse deleteHold(UserModel user, String holdNodeRef)
{
return deleteHold(user.getUsername(), user.getPassword(), holdNodeRef, SC_OK);
}
/**
* Deletes hold using RM Actions API and expect a specific status code
*
* @param username user's username
* @param password its password
* @param holdNodeRef the hold node ref
* @return The HTTP Response or throws AssertionError if the returned status code is not as expected.
*/
public HttpResponse deleteHold(String username, String password, String holdNodeRef, int expectedStatusCode)
{
JSONObject requestParams = new JSONObject();
requestParams.put("name", "deleteHold");
requestParams.put("nodeRef", getNodeRefSpacesStore() + holdNodeRef);
return doPostJsonRequest(username, password, expectedStatusCode, requestParams, RM_ACTIONS_API);
}
/**
* Deletes hold using cmis
* Deletes hold
*
* @param username user's username
* @param password its password
@@ -211,10 +179,7 @@ public class HoldsAPI extends BaseAPI
*/
public HttpResponse addItemsToHolds(String user, String password, List<String> itemNodeRefs, List<String> holdNames)
{
final List<String> holdNodeRefs = holdNames.stream()
.map(hold -> getItemNodeRef(user, password, String.format("/%s/%s", HOLDS_CONTAINER, hold)))
.collect(Collectors.toList());
return addItemsToHolds(user, password, SC_OK, itemNodeRefs, holdNodeRefs);
return addItemsToHolds(user, password, SC_OK, itemNodeRefs, holdNames);
}
/**
@@ -223,13 +188,13 @@ public class HoldsAPI extends BaseAPI
* @param user the user who adds the items to the holds
* @param password the user's password
* @param itemNodeRefs the list of items nodeRefs to be added to holds
* @param holdNodeRefs the list of holds
* @param holdNames the list of holds
* @return The HTTP response
*/
public HttpResponse addItemsToHolds(String user, String password, int expectedStatus, List<String> itemNodeRefs,
List<String> holdNodeRefs)
List<String> holdNames)
{
final JSONObject requestParams = addOrRemoveToFromHoldJsonObject(itemNodeRefs, holdNodeRefs);
final JSONObject requestParams = addOrRemoveToFromHoldJsonObject(user, password, itemNodeRefs, holdNames);
return doPostJsonRequest(user, password, expectedStatus, requestParams, RM_HOLDS_API);
}
@@ -239,30 +204,35 @@ public class HoldsAPI extends BaseAPI
* @param user the user who adds the item to the hold
* @param password the user's password
* @param itemNodeRef the nodeRef of the item to be added to hold
* @param holdNodeRef the hold node ref
* @param holdName the hold name
* @return The error message
*/
public String addToHoldAndGetMessage(String user, String password, int expectedStatus, String itemNodeRef, String
holdNodeRef)
holdName)
{
final HttpResponse httpResponse = addItemsToHolds(user, password, expectedStatus, Collections.singletonList(itemNodeRef),
Collections.singletonList(holdNodeRef));
Collections.singletonList(holdName));
return APIUtils.extractErrorMessageFromHttpResponse(httpResponse);
}
/**
* Util method to create the request body used when adding items to holds or when removing items from holds
*
* @param items list of items node refs to be added to holds
* @param holdNodeRefs list of hold node refs for add/remove items
* @param user user to create the request body for add/remove an item to/from hold
* @param password the user's password
* @param items list of items node refs to be added to holds
* @param holdNames list of hold names for add/remove items
* @return JSONObject fo
*/
private JSONObject addOrRemoveToFromHoldJsonObject(List<String> items, List<String> holdNodeRefs)
private JSONObject addOrRemoveToFromHoldJsonObject(String user, String password, List<String> items, List<String> holdNames)
{
final JSONArray nodeRefs = new JSONArray();
items.forEach(itemNodeRef -> nodeRefs.put(getNodeRefSpacesStore() + itemNodeRef));
final List<String> holdNodeRefs = holdNames.stream().map(hold ->
getNodeRefSpacesStore() + getItemNodeRef(user, password, String.format("/%s/%s", HOLDS_CONTAINER, hold)))
.collect(Collectors.toList());
final JSONArray holds = new JSONArray();
holdNodeRefs.forEach(holdNodeRef -> holds.put(getNodeRefSpacesStore() + holdNodeRef));
holdNodeRefs.forEach(holds::put);
final JSONObject requestParams = new JSONObject();
requestParams.put("nodeRefs", nodeRefs);
requestParams.put("holds", holds);
@@ -294,10 +264,7 @@ public class HoldsAPI extends BaseAPI
*/
public HttpResponse removeItemsFromHolds(String user, String password, List<String> itemNodeRefs, List<String> holdNames)
{
final List<String> holdNodeRefs = holdNames.stream()
.map(hold -> getItemNodeRef(user, password, String.format("/%s/%s", HOLDS_CONTAINER, hold)))
.collect(Collectors.toList());
return removeItemsFromHolds(user, password, SC_OK, itemNodeRefs, holdNodeRefs);
return removeItemsFromHolds(user, password, SC_OK, itemNodeRefs, holdNames);
}
/**
@@ -307,13 +274,13 @@ public class HoldsAPI extends BaseAPI
* @param password the user's password
* @param expectedStatus https status code expected
* @param itemNodeRefs the list of items nodeRefs to be removed from hold
* @param holdNodeRefs the list of hold node refs
* @param holdNames the list of hold names
* @return The HTTP response
*/
public HttpResponse removeItemsFromHolds(String user, String password, int expectedStatus, List<String> itemNodeRefs,
List<String> holdNodeRefs)
List<String> holdNames)
{
final JSONObject requestParams = addOrRemoveToFromHoldJsonObject(itemNodeRefs, holdNodeRefs);
final JSONObject requestParams = addOrRemoveToFromHoldJsonObject(user, password, itemNodeRefs, holdNames);
return doPutJsonRequest(user, password, expectedStatus, requestParams, RM_HOLDS_API);
}
@@ -323,14 +290,14 @@ public class HoldsAPI extends BaseAPI
* @param user the user who removes the item from hold
* @param password the user's password
* @param itemNodeRef the nodeRef of the item to be removed from hold
* @param holdNodeRef the hold node ref
* @param holdName the hold name
* @return The error message
*/
public String removeFromHoldAndGetMessage(String user, String password, int expectedStatus, String itemNodeRef, String
holdNodeRef)
holdName)
{
final HttpResponse httpResponse = removeItemsFromHolds(user, password, expectedStatus, Collections.singletonList(itemNodeRef),
Collections.singletonList(holdNodeRef));
Collections.singletonList(holdName));
return APIUtils.extractErrorMessageFromHttpResponse(httpResponse);
}

View File

@@ -76,7 +76,7 @@ public class RMAuditAPI extends BaseAPI
}
catch (UnsupportedEncodingException e)
{
LOGGER.error("Unable to encode the event name {}", e.getMessage());
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");

View File

@@ -102,7 +102,7 @@ public class SearchAPI extends BaseAPI
String filters,
String sortby)
{
List<BasicNameValuePair> searchParameters = new ArrayList<>();
List<BasicNameValuePair> searchParameters = new ArrayList<BasicNameValuePair>();
searchParameters.add(new BasicNameValuePair("query", query));
searchParameters.add(new BasicNameValuePair("filters", filters));
if (sortby != null)

View File

@@ -1,130 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2020 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.rest.v0.service;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.testng.AssertJUnit.assertTrue;
import java.time.Instant;
import java.util.List;
import org.alfresco.rest.rm.community.model.audit.AuditEntry;
import org.alfresco.rest.rm.community.model.audit.AuditEvents;
import org.alfresco.rest.v0.RMAuditAPI;
import org.alfresco.utility.data.DataUser;
import org.alfresco.utility.model.UserModel;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* Produces processed results from RM Audit REST API calls
*
* @author Claudia Agache
* @since 3.3
*/
@Service
public class RMAuditService
{
@Autowired
private RMAuditAPI rmAuditAPI;
@Autowired
private DataUser dataUser;
/**
* Clear the list of audit entries as admin user.
*/
public void clearAuditLog()
{
STEP("Clean audit logs.");
rmAuditAPI.clearAuditLog(dataUser.getAdminUser().getUsername(), dataUser.getAdminUser().getPassword());
}
/**
* Returns a list of rm audit entries filtered by given event
*
* @param user the user who requests the list of rm audit entries
* @param auditEvent the event
* @return the list of audit entries matching the event
*/
public List<AuditEntry> getAuditEntriesFilteredByEvent(UserModel user, AuditEvents auditEvent)
{
STEP("Get the list of audit entries for the " + auditEvent.eventDisplayName + " event.");
return rmAuditAPI.getRMAuditLog(user.getUsername(), user.getPassword(), 100, auditEvent.event);
}
/**
* Checks the rm audit log contains the entry for the given event.
*
* @param user the user who checks the audit log
* @param auditEvent the audited event
* @param auditUser the user who did the audited event
* @param nodeName the audited node name if exists or empty string
* @param changedValues the values changed by event if exist or empty list
*/
public void checkAuditLogForEvent(UserModel user, AuditEvents auditEvent, UserModel auditUser,
String nodeName, List<Object> changedValues)
{
final Instant eventTimestamp = Instant.now();
List<AuditEntry> auditEntries = getAuditEntriesFilteredByEvent(user, auditEvent);
assertTrue("The list of events is not filtered by " + auditEvent.event,
auditEntries.stream().allMatch(auditEntry -> auditEntry.getEvent().equals(auditEvent.eventDisplayName)));
assertTrue("The event details are not audited",
auditEntries.stream().anyMatch(auditEntry -> auditEntry.getNodeName().equals(nodeName) &&
auditEntry.getUserName().equals(auditUser.getUsername()) &&
CollectionUtils.isEqualCollection(auditEntry.getChangedValues(), changedValues) &&
!auditEntry.getTimestamp().isEmpty() &&
Instant.parse(auditEntry.getTimestamp()).compareTo(eventTimestamp) <= 0));
}
/**
* Checks the rm audit log contains the entry for the given event.
*
* @param user the user who checks the audit log
* @param auditEvent the audited event
* @param auditUser the user who did the audited event
* @param nodeName the audited node name if exists or empty string
* @param nodePath the path of the audited node if exists or empty string
* @param changedValues the values changed by event if exist or empty list
*/
public void checkAuditLogForEvent(UserModel user, AuditEvents auditEvent, UserModel auditUser,
String nodeName, String nodePath, List<Object> changedValues)
{
final Instant eventTimestamp = Instant.now();
List<AuditEntry> auditEntries = getAuditEntriesFilteredByEvent(user, auditEvent);
assertTrue("The list of events is not filtered by " + auditEvent.event,
auditEntries.stream().allMatch(auditEntry -> auditEntry.getEvent().equals(auditEvent.eventDisplayName)));
assertTrue("The event details are not audited",
auditEntries.stream().anyMatch(auditEntry -> auditEntry.getNodeName().equals(nodeName) &&
auditEntry.getUserName().equals(auditUser.getUsername()) &&
auditEntry.getPath().equals(nodePath) &&
CollectionUtils.isEqualCollection(auditEntry.getChangedValues(), changedValues) &&
!auditEntry.getTimestamp().isEmpty() &&
Instant.parse(auditEntry.getTimestamp()).compareTo(eventTimestamp) <= 0));
}
}

View File

@@ -1,310 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2020 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.rest.rm.community.audit;
import static java.util.Arrays.asList;
import static org.alfresco.rest.rm.community.base.TestData.HOLD_DESCRIPTION;
import static org.alfresco.rest.rm.community.base.TestData.HOLD_REASON;
import static org.alfresco.rest.rm.community.model.audit.AuditEvents.ADD_TO_HOLD;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.rest.rm.community.utils.RMSiteUtil.FILE_PLAN_PATH;
import static org.alfresco.utility.Utility.buildPath;
import static org.alfresco.utility.Utility.removeLastSlash;
import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.apache.commons.httpclient.HttpStatus.SC_INTERNAL_SERVER_ERROR;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertTrue;
import java.util.Collections;
import java.util.List;
import com.google.common.collect.ImmutableMap;
import org.alfresco.dataprep.CMISUtil;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.audit.AuditEntry;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.user.UserPermissions;
import org.alfresco.rest.rm.community.model.user.UserRoles;
import org.alfresco.rest.v0.HoldsAPI;
import org.alfresco.rest.v0.service.RMAuditService;
import org.alfresco.rest.v0.service.RoleService;
import org.alfresco.test.AlfrescoTest;
import org.alfresco.utility.constants.UserRole;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.SiteModel;
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.DataProvider;
import org.testng.annotations.Test;
/**
* This class contains the tests that check the add to hold event is audited
*
* @author Claudia Agache
* @since 3.3
*/
@AlfrescoTest (jira = "RM-6859")
public class AuditAddToHoldTests extends BaseRMRestTest
{
private final String PREFIX = generateTestPrefix(AuditAddToHoldTests.class);
private final String HOLD1 = PREFIX + "hold1";
private final String HOLD2 = PREFIX + "hold2";
@Autowired
private RMAuditService rmAuditService;
@Autowired
private HoldsAPI holdsAPI;
@Autowired
private RoleService roleService;
private UserModel rmAdmin, rmManagerNoReadOnHold, rmManagerNoReadOnNode;
private SiteModel privateSite;
private RecordCategory recordCategory;
private RecordCategoryChild recordFolder;
private List<AuditEntry> auditEntries;
private List<String> holdsList = asList(HOLD1, HOLD2);
private String hold1NodeRef;
@BeforeClass (alwaysRun = true)
public void preconditionForAuditAddToHoldTests() throws Exception
{
STEP("Create 2 holds.");
hold1NodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(),
getAdminUser().getPassword(), HOLD1, HOLD_REASON, HOLD_DESCRIPTION);
holdsAPI.createHold(getAdminUser().getUsername(), getAdminUser().getPassword(), HOLD2, HOLD_REASON, HOLD_DESCRIPTION);
STEP("Create a new record category with a record folder.");
recordCategory = createRootCategory(getRandomName("recordCategory"));
recordFolder = createRecordFolder(recordCategory.getId(), PREFIX + "recFolder");
STEP("Create an user with full rights to add content to a hold.");
rmAdmin = roleService.createUserWithRMRole(UserRoles.ROLE_RM_ADMIN.roleId);
STEP("Create a collaboration site.");
privateSite = dataSite.usingUser(rmAdmin).createPrivateRandomSite();
STEP("Create users without rights to add content to a hold.");
rmManagerNoReadOnHold = roleService.createUserWithSiteRoleRMRoleAndPermission(privateSite,
UserRole.SiteManager, recordCategory.getId(), UserRoles.ROLE_RM_MANAGER, UserPermissions.PERMISSION_FILING);
rmManagerNoReadOnNode = roleService.createUserWithRMRoleAndRMNodePermission(UserRoles.ROLE_RM_MANAGER.roleId,
hold1NodeRef, UserPermissions.PERMISSION_FILING);
}
/**
* Data provider with valid nodes that can be added to a hold
*
* @return the node id, the node name and the node path
* @throws Exception
*/
@DataProvider (name = "validNodesForAddToHold")
public Object[][] getValidNodesForAddToHold() throws Exception
{
FileModel contentToBeAdded = dataContent.usingAdmin().usingSite(privateSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
RecordCategoryChild recordFolderToBeAdded = createRecordFolder(recordCategory.getId(), PREFIX + "recFolderToBeAdded");
Record recordToBeAdded = createElectronicRecord(recordFolder.getId(), PREFIX + "record");
String recordFolderPath = removeLastSlash(buildPath(FILE_PLAN_PATH, recordCategory.getName(),
recordFolderToBeAdded.getName()));
String recordPath = removeLastSlash(buildPath(FILE_PLAN_PATH, recordCategory.getName(),
recordFolder.getName(), recordToBeAdded.getName()));
String contentPath = "/Company Home" + contentToBeAdded.getCmisLocation();
return new String[][]
{
// a record folder
{ recordFolderToBeAdded.getId(), recordFolderToBeAdded.getName(), recordFolderPath },
// a record
{ recordToBeAdded.getId(), recordToBeAdded.getName(), recordPath },
//an active content,
{ contentToBeAdded.getNodeRefWithoutVersion(), contentToBeAdded.getName(), contentPath }
};
}
/**
* Given a document/record/record folder is added to a hold
* When I view the audit log
* Then an entry has been created in the audit log that contains the following:
* name of the hold
* name of the document/record/record folder added
* user who added the content
* date the content was added
* path of the node
*/
@Test (dataProvider = "validNodesForAddToHold")
public void addToHoldEventIsAudited(String nodeId, String nodeName, String nodePath)
{
rmAuditService.clearAuditLog();
STEP("Add node to hold.");
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), nodeId, HOLD1);
STEP("Check the audit log contains the entry for the add to hold event.");
rmAuditService.checkAuditLogForEvent(getAdminUser(), ADD_TO_HOLD, rmAdmin, nodeName, nodePath,
asList(ImmutableMap.of("new", nodeName, "previous", "", "name", "Name"),
ImmutableMap.of("new", HOLD1, "previous", "", "name", "Hold Name")));
}
/**
* Given an unsuccessful add to hold action
* When I view the audit log
* Then the add to hold event isn't audited
*/
@Test
public void unsuccessfulAddToHoldIsNotAudited() throws Exception
{
STEP("Create a new record");
Record recordToBeAdded = createElectronicRecord(recordFolder.getId(), PREFIX + "record");
rmAuditService.clearAuditLog();
STEP("Try to add the record to a hold by an user with no rights.");
holdsAPI.addItemsToHolds(rmManagerNoReadOnHold.getUsername(), rmManagerNoReadOnHold.getPassword(),
SC_INTERNAL_SERVER_ERROR, Collections.singletonList(recordToBeAdded.getId()),
Collections.singletonList(hold1NodeRef));
STEP("Check the audit log doesn't contain the entry for the unsuccessful add to hold.");
assertTrue("The list of events should not contain Add to Hold entry ",
rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), ADD_TO_HOLD).isEmpty());
}
/**
* Given a not empty record folder is added to a hold
* When I view the audit log
* Then only an entry has been created in the audit log for the record folder added
*/
@Test
public void addToHoldIsNotAuditedForRecordFolderChildren() throws Exception
{
STEP("Create a new record folder with a record inside");
RecordCategoryChild notEmptyRecFolder = createRecordFolder(recordCategory.getId(), PREFIX + "notEmptyRecFolder");
Record record = createElectronicRecord(notEmptyRecFolder.getId(), PREFIX + "record");
rmAuditService.clearAuditLog();
STEP("Add record folder to hold.");
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), notEmptyRecFolder.getId(), HOLD1);
auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), ADD_TO_HOLD);
STEP("Check the audit log contains only an entry for add to hold.");
assertEquals("The list of events should contain only an entry", 1, auditEntries.size());
assertTrue("The list of events should not contain Add to Hold entry for the record",
auditEntries.stream().noneMatch(entry -> entry.getNodeName().equals(record.getName())));
}
/**
* Given a record is added to multiple holds
* When I view the audit log
* Then multiple entries have been created in the audit log for each add to hold event
*/
@Test
public void addToHoldIsAuditedInBulkAddition() throws Exception
{
STEP("Create a new record");
Record recordToBeAdded = createElectronicRecord(recordFolder.getId(), PREFIX + "record");
rmAuditService.clearAuditLog();
STEP("Add record to multiple holds.");
holdsAPI.addItemsToHolds(rmAdmin.getUsername(), rmAdmin.getPassword(),
Collections.singletonList(recordToBeAdded.getId()), holdsList);
auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), ADD_TO_HOLD);
STEP("Check the audit log contains entries for both additions.");
assertEquals("The list of events should contain Add to Hold entries for both holds", 2, auditEntries.size());
assertTrue("The hold name value for the first add to hold is not audited.",
auditEntries.stream().anyMatch(entry -> entry.getChangedValues().contains(
ImmutableMap.of("new", HOLD1, "previous", "", "name", "Hold Name"))));
assertTrue("The hold name value for the second add to hold is not audited.",
auditEntries.stream().anyMatch(entry -> entry.getChangedValues().contains(
ImmutableMap.of("new", HOLD2, "previous", "", "name", "Hold Name"))));
}
/**
* Given a document is added to a hold
* When I view the audit log as an user with no Read permissions over the document
* Then the add to hold entry isn't visible
*/
@Test
public void addToHoldAuditEntryNotVisible()
{
STEP("Create a new file");
FileModel contentToBeAdded = dataContent.usingAdmin().usingSite(privateSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
rmAuditService.clearAuditLog();
STEP("Add file to hold.");
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), contentToBeAdded.getNodeRefWithoutVersion(), HOLD1);
STEP("Check that an user with no Read permissions can't see the entry for the add to hold event.");
assertTrue("The list of events should not contain Add to Hold entry ",
rmAuditService.getAuditEntriesFilteredByEvent(rmManagerNoReadOnNode, ADD_TO_HOLD).isEmpty());
}
/**
* Given a document is added to a hold
* When I view the audit log as an user with no Read permissions over the hold
* Then the the hold name is replaced in the add to hold entry
*/
@Test
public void addToHoldAuditEntryHoldNameNotVisible()
{
STEP("Create a new file");
FileModel contentToBeAdded = dataContent.usingAdmin().usingSite(privateSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
rmAuditService.clearAuditLog();
STEP("Add file to hold.");
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), contentToBeAdded.getNodeRefWithoutVersion(), HOLD1);
auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(rmManagerNoReadOnHold, ADD_TO_HOLD);
STEP("Check that an user with no Read permissions can't see the hold name in the add to hold event.");
String replacementHoldName = "You don't have permission to view this hold.";
assertEquals("The list of events should contain the Add to Hold entry", 1, auditEntries.size());
assertTrue("The hold name should not be visible in the Add to Hold entry ",
auditEntries.stream().anyMatch(entry -> entry.getChangedValues().contains(
ImmutableMap.of("new", replacementHoldName, "previous", "", "name", "Hold Name"))));
}
@AfterClass (alwaysRun = true)
public void cleanUpAuditAddToHoldTests()
{
holdsList.forEach(hold -> holdsAPI.deleteHold(getAdminUser().getUsername(), getAdminUser().getPassword(), hold));
dataSite.usingAdmin().deleteSite(privateSite);
asList(rmAdmin, rmManagerNoReadOnHold, rmManagerNoReadOnNode).forEach(user -> getDataUser().usingAdmin().deleteUser(user));
getRestAPIFactory().getRecordCategoryAPI().deleteRecordCategory(recordCategory.getId());
}
}

View File

@@ -1,185 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2020 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.rest.rm.community.audit;
import static java.util.Arrays.asList;
import static org.alfresco.rest.rm.community.base.TestData.HOLD_DESCRIPTION;
import static org.alfresco.rest.rm.community.base.TestData.HOLD_REASON;
import static org.alfresco.rest.rm.community.model.audit.AuditEvents.CREATE_HOLD;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.apache.commons.httpclient.HttpStatus.SC_INTERNAL_SERVER_ERROR;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertTrue;
import java.util.List;
import com.google.common.collect.ImmutableMap;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.audit.AuditEntry;
import org.alfresco.rest.rm.community.model.user.UserRoles;
import org.alfresco.rest.v0.HoldsAPI;
import org.alfresco.rest.v0.service.RMAuditService;
import org.alfresco.rest.v0.service.RoleService;
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 create hold event is audited
*
* @author Claudia Agache
* @since 3.3
*/
@AlfrescoTest (jira = "RM-6859")
public class AuditCreateHoldTests extends BaseRMRestTest
{
private final String PREFIX = generateTestPrefix(AuditCreateHoldTests.class);
private final String HOLD1 = PREFIX + "createHold";
private final String HOLD2 = PREFIX + "createHold2";
private final String HOLD3 = PREFIX + "createHold3";
@Autowired
private RMAuditService rmAuditService;
@Autowired
private HoldsAPI holdsAPI;
@Autowired
private RoleService roleService;
private UserModel rmAdmin, rmManager;
@BeforeClass (alwaysRun = true)
public void preconditionForAuditCreateHoldTests()
{
STEP("Create test users.");
rmAdmin = roleService.createUserWithRMRole(UserRoles.ROLE_RM_ADMIN.roleId);
rmManager = roleService.createUserWithRMRole(UserRoles.ROLE_RM_MANAGER.roleId);
}
/**
* Given a new hold is created
* When I view the audit log
* Then an entry has been created in the audit log which contains the following:
* name of the hold
* reason for hold
* user who created the hold
* date the creation occurred
*/
@Test
public void createHoldEventIsAuditedForNewHold()
{
rmAuditService.clearAuditLog();
STEP("Create a new hold.");
holdsAPI.createHold(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD1, HOLD_REASON, HOLD_DESCRIPTION);
STEP("Check the audit log contains the entry for the created hold with the hold details.");
rmAuditService.checkAuditLogForEvent(getAdminUser(), CREATE_HOLD, rmAdmin, HOLD1,
asList(ImmutableMap.of("new", HOLD_REASON, "previous", "", "name", "Hold Reason"),
ImmutableMap.of("new", HOLD1, "previous", "", "name", "Hold Name")));
}
/**
* Given an unsuccessful create hold action
* When I view the audit log
* Then the create hold event isn't audited
*/
@Test
public void createHoldEventIsNotAuditedForExistingHold()
{
STEP("Create a new hold.");
holdsAPI.createHold(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD2, HOLD_REASON, HOLD_DESCRIPTION);
rmAuditService.clearAuditLog();
STEP("Try to create again the same hold and expect action to fail.");
holdsAPI.createHold(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD2, HOLD_REASON, HOLD_DESCRIPTION,
SC_INTERNAL_SERVER_ERROR);
STEP("Check the audit log doesn't contain the entry for the second create hold event.");
assertTrue("The list of events should not contain Create Hold entry ",
rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), CREATE_HOLD).isEmpty());
}
/**
* Given a new hold is created and then deleted
* When I view the audit log
* Then the create hold entry still contains the initial details
*/
@Test
public void createHoldAuditEntryIsNotLost()
{
final String holdName = PREFIX + "holdToBeDeleted";
rmAuditService.clearAuditLog();
STEP("Create a new hold.");
holdsAPI.createHold(rmAdmin.getUsername(), rmAdmin.getPassword(), holdName, HOLD_REASON, HOLD_DESCRIPTION);
STEP("Get the list of audit entries for the create hold event.");
List<AuditEntry> auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), CREATE_HOLD);
STEP("Delete the created hold.");
holdsAPI.deleteHold(rmAdmin.getUsername(), rmAdmin.getPassword(), holdName);
STEP("Get again the list of audit entries for the create hold event.");
List<AuditEntry> auditEntriesAfterDelete = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), CREATE_HOLD);
STEP("Check that the audit entry for the created hold didn't change after hold deletion.");
assertEquals("The audit entry for Create Hold has been changed", auditEntries, auditEntriesAfterDelete);
}
/**
* Given a new hold is created
* When I view the audit log as an user with no Read permissions over the created hold
* Then the create hold entry isn't visible
*/
@Test
public void createHoldAuditEntryNotVisible()
{
rmAuditService.clearAuditLog();
STEP("Create a new hold.");
holdsAPI.createHold(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD3, HOLD_REASON, HOLD_DESCRIPTION);
STEP("Check that an user with no Read permissions over the hold can't see the entry for the create hold event");
assertTrue("The list of events should not contain Create Hold entry ",
rmAuditService.getAuditEntriesFilteredByEvent(rmManager, CREATE_HOLD).isEmpty());
}
@AfterClass (alwaysRun = true)
public void cleanUpAuditCreateHoldTests()
{
asList(HOLD1, HOLD2, HOLD3).forEach(hold ->
holdsAPI.deleteHold(getAdminUser().getUsername(), getAdminUser().getPassword(), hold));
asList(rmAdmin, rmManager).forEach(user -> getDataUser().usingAdmin().deleteUser(user));
}
}

View File

@@ -1,139 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2020 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.rest.rm.community.audit;
import static java.util.Arrays.asList;
import static org.alfresco.rest.rm.community.base.TestData.HOLD_DESCRIPTION;
import static org.alfresco.rest.rm.community.base.TestData.HOLD_REASON;
import static org.alfresco.rest.rm.community.model.audit.AuditEvents.DELETE_HOLD;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.apache.commons.httpclient.HttpStatus.SC_INTERNAL_SERVER_ERROR;
import static org.testng.AssertJUnit.assertTrue;
import java.util.Collections;
import com.google.common.collect.ImmutableMap;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.user.UserRoles;
import org.alfresco.rest.v0.HoldsAPI;
import org.alfresco.rest.v0.service.RMAuditService;
import org.alfresco.rest.v0.service.RoleService;
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 delete hold event is audited
*
* @author Claudia Agache
* @since 3.3
*/
@AlfrescoTest (jira = "RM-6859")
public class AuditDeleteHoldTests extends BaseRMRestTest
{
private final String PREFIX = generateTestPrefix(AuditDeleteHoldTests.class);
private final String HOLD = PREFIX + "holdToBeDeleted";
private final String HOLD2 = PREFIX + "deleteHold";
@Autowired
private RMAuditService rmAuditService;
@Autowired
private HoldsAPI holdsAPI;
@Autowired
private RoleService roleService;
private UserModel rmAdmin, rmManager;
private String holdNodeRef;
@BeforeClass (alwaysRun = true)
public void preconditionForAuditDeleteHoldTests()
{
STEP("Create a new hold.");
holdNodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser().getPassword(), HOLD,
HOLD_REASON, HOLD_DESCRIPTION);
STEP("Create 2 users with different permissions for the created hold.");
rmAdmin = roleService.createUserWithRMRole(UserRoles.ROLE_RM_ADMIN.roleId);
rmManager = roleService.createUserWithRMRole(UserRoles.ROLE_RM_MANAGER.roleId);
}
/**
* Given a hold is deleted
* When I view the audit log
* Then an entry has been created in the audit log which contains the following:
* name of the hold
* user who deleted the hold
* date the delete occurred
*/
@Test
public void deleteHoldEventIsAudited()
{
STEP("Create a new hold.");
String holdRef = holdsAPI.createHoldAndGetNodeRef(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD2,
HOLD_REASON, HOLD_DESCRIPTION);
rmAuditService.clearAuditLog();
STEP("Delete the created hold.");
holdsAPI.deleteHold(rmAdmin, holdRef);
STEP("Check the audit log contains the entry for the deleted hold with the hold details.");
rmAuditService.checkAuditLogForEvent(getAdminUser(), DELETE_HOLD, rmAdmin, HOLD2,
Collections.singletonList(ImmutableMap.of("new", "", "previous", HOLD2, "name", "Hold Name")));
}
/**
* Given an unsuccessful delete hold action
* When I view the audit log
* Then the delete hold event isn't audited
*/
@Test
public void unsuccessfulDeleteHoldIsNotAudited()
{
rmAuditService.clearAuditLog();
STEP("Try to delete a hold by an user with no Read permissions over the hold.");
holdsAPI.deleteHold(rmManager.getUsername(), rmManager.getPassword(), holdNodeRef, SC_INTERNAL_SERVER_ERROR);
STEP("Check the audit log doesn't contain the entry for the unsuccessful delete hold.");
assertTrue("The list of events should not contain Delete Hold entry ",
rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), DELETE_HOLD).isEmpty());
}
@AfterClass (alwaysRun = true)
public void cleanUpAuditDeleteHoldTests()
{
holdsAPI.deleteHold(getAdminUser().getUsername(), getAdminUser().getPassword(), HOLD);
asList(rmAdmin, rmManager).forEach(user -> getDataUser().usingAdmin().deleteUser(user));
}
}

View File

@@ -26,20 +26,20 @@
*/
package org.alfresco.rest.rm.community.audit;
import static java.util.Arrays.asList;
import static org.alfresco.rest.rm.community.model.audit.AuditEvents.ADD_TO_USER_GROUP;
import static org.alfresco.rest.rm.community.model.audit.AuditEvents.CREATE_USER_GROUP;
import static org.alfresco.rest.rm.community.model.audit.AuditEvents.DELETE_USER_GROUP;
import static org.alfresco.rest.rm.community.model.audit.AuditEvents.REMOVE_FROM_USER_GROUP;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.testng.AssertJUnit.assertTrue;
import java.util.Collections;
import java.util.List;
import com.google.common.collect.ImmutableMap;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.v0.service.RMAuditService;
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.GroupModel;
import org.alfresco.utility.model.UserModel;
@@ -57,14 +57,16 @@ import org.testng.annotations.Test;
public class AuditGroupEventsTests extends BaseRMRestTest
{
@Autowired
private RMAuditService rmAuditService;
private RMAuditAPI rmAuditAPI;
private GroupModel testGroup;
private UserModel testUser;
@BeforeClass (alwaysRun = true)
public void cleanAuditLogs()
{
rmAuditService.clearAuditLog();
//clean audit logs
rmAuditAPI.clearAuditLog(getAdminUser().getUsername(), getAdminUser().getPassword());
}
/**
@@ -77,10 +79,17 @@ public class AuditGroupEventsTests extends BaseRMRestTest
{
testGroup = dataGroup.createRandomGroup();
STEP("Check the audit log contains the entry for the created group.");
rmAuditService.checkAuditLogForEvent(getAdminUser(), CREATE_USER_GROUP, getAdminUser(), testGroup.getGroupIdentifier(),
Collections.singletonList(ImmutableMap.of("new", testGroup.getGroupIdentifier(), "previous", "",
"name", "authorityDisplayName")));
STEP("Get the list of audit entries for the create group event.");
List<AuditEntry> auditEntries = rmAuditAPI.getRMAuditLog(getAdminUser().getUsername(),
getAdminUser().getPassword(), 100, CREATE_USER_GROUP.event);
STEP("Check the audit log contains only the entries for the created group.");
assertTrue("The list of events is not filtered by " + CREATE_USER_GROUP.event,
auditEntries.stream().allMatch(auditEntry -> auditEntry.getEvent().equals(CREATE_USER_GROUP.eventDisplayName)));
assertTrue("The group name for the new group created is not audited.",
auditEntries.stream().filter(auditEntry -> auditEntry.getEvent().equals(CREATE_USER_GROUP.eventDisplayName))
.anyMatch(auditEntry -> auditEntry.getNodeName().equals(testGroup.getGroupIdentifier())));
}
/**
@@ -95,10 +104,19 @@ public class AuditGroupEventsTests extends BaseRMRestTest
testUser = getDataUser().createRandomTestUser();
dataGroup.usingUser(testUser).addUserToGroup(testGroup);
STEP("Check the audit log contains the entry for the add user to group event.");
rmAuditService.checkAuditLogForEvent(getAdminUser(), ADD_TO_USER_GROUP, getAdminUser(), testGroup.getGroupIdentifier(),
asList(ImmutableMap.of("new", testUser.getUsername(), "previous", "", "name", "User Name"),
ImmutableMap.of("new", testGroup.getGroupIdentifier(), "previous", "", "name", "Parent Group")));
STEP("Get the list of audit entries for the add user to group event.");
List<AuditEntry> auditEntries = rmAuditAPI.getRMAuditLog(getAdminUser().getUsername(),
getAdminUser().getPassword(), 100, ADD_TO_USER_GROUP.event);
STEP("Check the audit log contains only the entries for the add user to group event.");
assertTrue("The list of events is not filtered by " + ADD_TO_USER_GROUP.event,
auditEntries.stream().allMatch(auditEntry -> auditEntry.getEvent().equals(ADD_TO_USER_GROUP.eventDisplayName)));
assertTrue("The username and destination group are not audited.",
auditEntries.stream().filter(auditEntry -> auditEntry.getEvent().equals(ADD_TO_USER_GROUP.eventDisplayName))
.anyMatch(auditEntry -> auditEntry.getNodeName().equals(testGroup.getGroupIdentifier())
&& auditEntry.getChangedValues().contains(ImmutableMap.of("new", testUser.getUsername(), "previous", "", "name", "User Name"))
&& auditEntry.getChangedValues().contains(ImmutableMap.of("new", testGroup.getGroupIdentifier(), "previous", "", "name", "Parent Group"))));
}
/**
@@ -114,10 +132,19 @@ public class AuditGroupEventsTests extends BaseRMRestTest
dataGroup.usingUser(testUser).addUserToGroup(testGroup);
dataGroup.removeUserFromGroup(testGroup, testUser);
STEP("Check the audit log contains the entry for the remove user from group event.");
rmAuditService.checkAuditLogForEvent(getAdminUser(), REMOVE_FROM_USER_GROUP, getAdminUser(), testGroup.getGroupIdentifier(),
asList(ImmutableMap.of("new", "", "previous", testUser.getUsername(), "name", "User Name"),
ImmutableMap.of("new", "","previous", testGroup.getGroupIdentifier(), "name", "Parent Group")));
STEP("Get the list of audit entries for the add user to group event.");
List<AuditEntry> auditEntries = rmAuditAPI.getRMAuditLog(getAdminUser().getUsername(),
getAdminUser().getPassword(), 100, REMOVE_FROM_USER_GROUP.event);
STEP("Check the audit log contains only the entries for the remove user from group event.");
assertTrue("The list of events is not filtered by " + REMOVE_FROM_USER_GROUP.event,
auditEntries.stream().allMatch(auditEntry -> auditEntry.getEvent().equals(REMOVE_FROM_USER_GROUP.eventDisplayName)));
assertTrue("The username and previous parent group are not audited.",
auditEntries.stream().filter(auditEntry -> auditEntry.getEvent().equals(REMOVE_FROM_USER_GROUP.eventDisplayName))
.anyMatch(auditEntry -> auditEntry.getNodeName().equals(testGroup.getGroupIdentifier())
&& auditEntry.getChangedValues().contains(ImmutableMap.of("new", "", "previous", testUser.getUsername(), "name", "User Name"))
&& auditEntry.getChangedValues().contains(ImmutableMap.of("new", "","previous", testGroup.getGroupIdentifier(), "name", "Parent Group"))));
}
/**
@@ -131,9 +158,17 @@ public class AuditGroupEventsTests extends BaseRMRestTest
testGroup = dataGroup.createRandomGroup();
dataGroup.deleteGroup(testGroup);
STEP("Check the audit log contains the entry for the delete group event.");
rmAuditService.checkAuditLogForEvent(getAdminUser(), DELETE_USER_GROUP, getAdminUser(), testGroup.getGroupIdentifier(),
Collections.singletonList(ImmutableMap.of("new", "", "previous", testGroup.getGroupIdentifier(),
"name", "authorityDisplayName")));
STEP("Get the list of audit entries for the delete group event.");
List<AuditEntry> auditEntries = rmAuditAPI.getRMAuditLog(getAdminUser().getUsername(),
getAdminUser().getPassword(), 100, DELETE_USER_GROUP.event);
STEP("Check the audit log contains only the entries for the created group.");
assertTrue("The list of events is not filtered by " + DELETE_USER_GROUP.event,
auditEntries.stream().allMatch(auditEntry -> auditEntry.getEvent().equals(DELETE_USER_GROUP.eventDisplayName)));
assertTrue("The group name for the deleted group is not audited.",
auditEntries.stream().filter(auditEntry -> auditEntry.getEvent().equals(DELETE_USER_GROUP.eventDisplayName))
.anyMatch(auditEntry -> auditEntry.getNodeName().equals(testGroup.getGroupIdentifier())
&& auditEntry.getChangedValues().contains(ImmutableMap.of("new", "", "previous", testGroup.getGroupIdentifier(), "name", "authorityDisplayName"))));
}
}

View File

@@ -34,10 +34,11 @@ 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.service.RMAuditService;
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.BeforeClass;
import org.testng.annotations.Test;
/**
@@ -50,7 +51,14 @@ import org.testng.annotations.Test;
public class AuditLoginEventsTests extends BaseRMRestTest
{
@Autowired
private RMAuditService rmAuditService;
private RMAuditAPI rmAuditAPI;
@BeforeClass (alwaysRun = true)
public void cleanAuditLogs()
{
//clean audit logs
rmAuditAPI.clearAuditLog(getAdminUser().getUsername(), getAdminUser().getPassword());
}
/**
* Given I have tried to login using invalid credentials
@@ -60,13 +68,12 @@ public class AuditLoginEventsTests extends BaseRMRestTest
@Test
public void filterByLoginUnsuccessful() throws Exception
{
rmAuditService.clearAuditLog();
restClient.authenticateUser(new UserModel(getAdminUser().getUsername(), "InvalidPassword"));
restClient.withCoreAPI().getSites();
STEP("Get the list of audit entries for the login unsuccessful event.");
List<AuditEntry> auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(),
LOGIN_UNSUCCESSFUL);
List<AuditEntry> auditEntries = rmAuditAPI.getRMAuditLog(getAdminUser().getUsername(),
getAdminUser().getPassword(), 100, LOGIN_UNSUCCESSFUL.event);
STEP("Check the audit log contains only the entries for the login unsuccessful event.");
assertTrue("The list of events is not filtered by " + LOGIN_UNSUCCESSFUL.event,

View File

@@ -1,325 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2020 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.rest.rm.community.audit;
import static java.util.Arrays.asList;
import static org.alfresco.rest.rm.community.base.TestData.HOLD_DESCRIPTION;
import static org.alfresco.rest.rm.community.base.TestData.HOLD_REASON;
import static org.alfresco.rest.rm.community.model.audit.AuditEvents.REMOVE_FROM_HOLD;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.rest.rm.community.utils.RMSiteUtil.FILE_PLAN_PATH;
import static org.alfresco.utility.Utility.buildPath;
import static org.alfresco.utility.Utility.removeLastSlash;
import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.apache.commons.httpclient.HttpStatus.SC_INTERNAL_SERVER_ERROR;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertTrue;
import java.util.Collections;
import java.util.List;
import com.google.common.collect.ImmutableMap;
import org.alfresco.dataprep.CMISUtil;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.audit.AuditEntry;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.user.UserPermissions;
import org.alfresco.rest.rm.community.model.user.UserRoles;
import org.alfresco.rest.v0.HoldsAPI;
import org.alfresco.rest.v0.service.RMAuditService;
import org.alfresco.rest.v0.service.RoleService;
import org.alfresco.test.AlfrescoTest;
import org.alfresco.utility.constants.UserRole;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.SiteModel;
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.DataProvider;
import org.testng.annotations.Test;
/**
* This class contains the tests that check the remove from hold event is audited
*
* @author Claudia Agache
* @since 3.3
*/
@AlfrescoTest (jira = "RM-6859")
public class AuditRemoveFromHoldTests extends BaseRMRestTest
{
private final String PREFIX = generateTestPrefix(AuditRemoveFromHoldTests.class);
private final String HOLD1 = PREFIX + "hold1";
private final String HOLD2 = PREFIX + "hold2";
private final String HOLD3 = PREFIX + "hold3";
private final String DELETED_HOLD = PREFIX + "deletedHold";
@Autowired
private RMAuditService rmAuditService;
@Autowired
private HoldsAPI holdsAPI;
@Autowired
private RoleService roleService;
private UserModel rmAdmin, rmManagerNoReadOnHold, rmManagerNoReadOnNode;
private SiteModel privateSite;
private RecordCategory recordCategory;
private RecordCategoryChild recordFolder, heldRecordFolder;
private Record heldRecord;
private List<AuditEntry> auditEntries;
private List<String> holdsList = asList(HOLD1, HOLD2, HOLD3);
private FileModel heldContent;
private String hold1NodeRef;
@BeforeClass (alwaysRun = true)
public void preconditionForAuditRemoveFromHoldTests() throws Exception
{
STEP("Create an user with full rights to remove content from a hold.");
rmAdmin = roleService.createUserWithRMRole(UserRoles.ROLE_RM_ADMIN.roleId);
STEP("Create a collaboration site.");
privateSite = dataSite.usingUser(rmAdmin).createPrivateRandomSite();
STEP("Create new holds.");
hold1NodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser().getPassword(),
HOLD1, HOLD_REASON, HOLD_DESCRIPTION);
holdsAPI.createHold(getAdminUser().getUsername(), getAdminUser().getPassword(), HOLD2, HOLD_REASON, HOLD_DESCRIPTION);
holdsAPI.createHold(getAdminUser().getUsername(), getAdminUser().getPassword(), HOLD3, HOLD_REASON, HOLD_DESCRIPTION);
holdsAPI.createHold(getAdminUser().getUsername(), getAdminUser().getPassword(), DELETED_HOLD, HOLD_REASON, HOLD_DESCRIPTION);
STEP("Create a new record category with a record folder.");
recordCategory = createRootCategory(getRandomName("recordCategory"));
recordFolder = createRecordFolder(recordCategory.getId(), getRandomName("recFolder"));
STEP("Create some held items");
heldContent = dataContent.usingAdmin().usingSite(privateSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
heldRecordFolder = createRecordFolder(recordCategory.getId(), PREFIX + "heldRecFolder");
heldRecord = createElectronicRecord(recordFolder.getId(), PREFIX + "record");
holdsAPI.addItemsToHolds(getAdminUser().getUsername(), getAdminUser().getPassword(),
asList(heldContent.getNodeRefWithoutVersion(), heldRecordFolder.getId(), heldRecord.getId()),
holdsList);
STEP("Create users without rights to remove content from a hold.");
rmManagerNoReadOnHold = roleService.createUserWithSiteRoleRMRoleAndPermission(privateSite,
UserRole.SiteManager, recordCategory.getId(), UserRoles.ROLE_RM_MANAGER, UserPermissions.PERMISSION_FILING);
rmManagerNoReadOnNode = roleService.createUserWithRMRoleAndRMNodePermission(UserRoles.ROLE_RM_MANAGER.roleId,
hold1NodeRef, UserPermissions.PERMISSION_FILING);
}
/**
* Data provider with valid nodes that can be removed from a hold
*
* @return the node id, the node name and the node path
*/
@DataProvider (name = "validNodesForRemoveFromHold")
public Object[][] getValidNodesForRemoveFromHold()
{
String recordFolderPath = removeLastSlash(buildPath(FILE_PLAN_PATH, recordCategory.getName(),
heldRecordFolder.getName()));
String recordPath = removeLastSlash(buildPath(FILE_PLAN_PATH, recordCategory.getName(),
recordFolder.getName(), heldRecord.getName()));
String contentPath = "/Company Home" + heldContent.getCmisLocation();
return new String[][]
{
// a record folder
{ heldRecordFolder.getId(), heldRecordFolder.getName(), recordFolderPath },
// a record
{ heldRecord.getId(), heldRecord.getName(), recordPath },
//an active content,
{ heldContent.getNodeRefWithoutVersion(), heldContent.getName(), contentPath }
};
}
/**
* Given a document/record/record folder is removed from a hold
* When I view the audit log
* Then an entry has been created in the audit log that contains the following:
* name of the hold
* name of the document/record/record folder removed
* user who removed the content
* date the content was removed
* path of the node
*/
@Test (dataProvider = "validNodesForRemoveFromHold")
public void removeFromHoldEventIsAudited(String nodeId, String nodeName, String nodePath)
{
rmAuditService.clearAuditLog();
STEP("Remove node from hold.");
holdsAPI.removeItemFromHold(rmAdmin.getUsername(), rmAdmin.getPassword(), nodeId, HOLD3);
STEP("Check the audit log contains the entry for the remove from hold event.");
rmAuditService.checkAuditLogForEvent(getAdminUser(), REMOVE_FROM_HOLD, rmAdmin, nodeName, nodePath,
asList(ImmutableMap.of("new", "", "previous", nodeName, "name", "Name"),
ImmutableMap.of("new", "", "previous", HOLD3, "name", "Hold Name")));
}
/**
* Given an unsuccessful remove from hold action
* When I view the audit log
* Then the remove from hold event isn't audited
*/
@Test
public void unsuccessfulRemoveFromHoldIsNotAudited()
{
rmAuditService.clearAuditLog();
STEP("Try to remove the record from a hold by an user with no rights.");
holdsAPI.removeItemsFromHolds(rmManagerNoReadOnHold.getUsername(), rmManagerNoReadOnHold.getPassword(),
SC_INTERNAL_SERVER_ERROR, Collections.singletonList(heldRecord.getId()),
Collections.singletonList(hold1NodeRef));
STEP("Check the audit log doesn't contain the entry for the unsuccessful remove from hold.");
assertTrue("The list of events should not contain remove from hold entry ",
rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), REMOVE_FROM_HOLD).isEmpty());
}
/**
* Given a not empty record folder is removed from a hold
* When I view the audit log
* Then only an entry has been created in the audit log for the record folder removed
*/
@Test
public void removeFromHoldNotAuditedForRecordFolderChildren() throws Exception
{
STEP("Create a new record folder with a record inside");
RecordCategoryChild notEmptyRecFolder = createRecordFolder(recordCategory.getId(), PREFIX + "notEmptyRecFolder");
Record record = createElectronicRecord(notEmptyRecFolder.getId(), PREFIX + "record");
STEP("Add the record folder to a hold.");
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), notEmptyRecFolder.getId(), HOLD1);
rmAuditService.clearAuditLog();
STEP("Remove record folder from hold.");
holdsAPI.removeItemFromHold(rmAdmin.getUsername(), rmAdmin.getPassword(), notEmptyRecFolder.getId(), HOLD1);
STEP("Get the list of audit entries for the remove from hold event.");
auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), REMOVE_FROM_HOLD);
STEP("Check the audit log contains only an entry for remove from hold.");
assertEquals("The list of events should contain only an entry", 1, auditEntries.size());
assertTrue("The list of events should not contain Remove from Hold entry for the record",
auditEntries.stream().noneMatch(entry -> entry.getNodeName().equals(record.getName())));
}
/**
* Given a record folder is removed from multiple holds
* When I view the audit log
* Then multiple entries have been created in the audit log for each remove from hold event
*/
@Test
public void removeFromHoldIsAuditedInBulkRemoval()
{
rmAuditService.clearAuditLog();
STEP("Remove record folder from multiple holds.");
holdsAPI.removeItemsFromHolds(rmAdmin.getUsername(), rmAdmin.getPassword(),
Collections.singletonList(heldRecordFolder.getId()), asList(HOLD1, HOLD2));
STEP("Get the list of audit entries for the remove from hold event.");
auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), REMOVE_FROM_HOLD);
STEP("Check the audit log contains entries for both removal.");
assertEquals("The list of events should contain remove from Hold entries for both holds", 2,
auditEntries.size());
assertTrue("The hold name value for the first remove from hold is not audited.",
auditEntries.stream().anyMatch(entry -> entry.getChangedValues().contains(
ImmutableMap.of("new", "", "previous", HOLD1, "name", "Hold Name"))));
assertTrue("The hold name value for the second remove from hold is not audited.",
auditEntries.stream().anyMatch(entry -> entry.getChangedValues().contains(
ImmutableMap.of("new", "", "previous", HOLD2, "name", "Hold Name"))));
}
/**
* Given a document/record/record folder is removed from a hold
* When I view the audit log as an user with no Read permissions over the node
* Then the remove from hold entry isn't visible
*/
@Test
public void removeFromHoldAuditEntryNotVisible()
{
STEP("Add content to a hold.");
FileModel heldFile = dataContent.usingAdmin().usingSite(privateSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), heldFile.getNodeRefWithoutVersion(), HOLD1);
rmAuditService.clearAuditLog();
STEP("Remove held content from the hold.");
holdsAPI.removeItemFromHold(rmAdmin.getUsername(), rmAdmin.getPassword(), heldFile.getNodeRefWithoutVersion(), HOLD1);
STEP("Check that an user with no Read permissions can't see the entry for the remove from hold event.");
assertTrue("The list of events should not contain Remove from Hold entry ",
rmAuditService.getAuditEntriesFilteredByEvent(rmManagerNoReadOnNode, REMOVE_FROM_HOLD).isEmpty());
}
/**
* Given a document/record/record folder is removed from a hold
* When I view the audit log as an user with no Read permissions over the hold
* Then the the hold name is replaced in the remove from hold entry
*/
@Test
public void removeFromHoldAuditEntryHoldNameNotVisible()
{
STEP("Add content to a hold.");
FileModel heldFile = dataContent.usingAdmin().usingSite(privateSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), heldFile.getNodeRefWithoutVersion(), HOLD1);
rmAuditService.clearAuditLog();
STEP("Remove held content from the hold.");
holdsAPI.removeItemFromHold(rmAdmin.getUsername(), rmAdmin.getPassword(), heldFile.getNodeRefWithoutVersion(), HOLD1);
auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(rmManagerNoReadOnHold, REMOVE_FROM_HOLD);
STEP("Check that an user with no Read permissions can't see the hold name in the remove from hold event.");
String replacementHoldName = "You don't have permission to view this hold.";
assertEquals("The list of events should contain the Remove from Hold entry", 1, auditEntries.size());
assertTrue("The hold name should not be visible in the Remove from Hold entry ",
auditEntries.stream().anyMatch(entry -> entry.getChangedValues().contains(
ImmutableMap.of("new", "", "previous", replacementHoldName, "name", "Hold Name"))));
}
@AfterClass (alwaysRun = true)
public void cleanUpAuditRemoveFromHoldTests()
{
holdsList.forEach(hold -> holdsAPI.deleteHold(getAdminUser().getUsername(), getAdminUser().getPassword(), hold));
dataSite.usingAdmin().deleteSite(privateSite);
asList(rmAdmin, rmManagerNoReadOnHold, rmManagerNoReadOnNode).forEach(user -> getDataUser().usingAdmin().deleteUser(user));
getRestAPIFactory().getRecordCategoryAPI().deleteRecordCategory(recordCategory.getId());
}
}

View File

@@ -29,17 +29,18 @@ 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.alfresco.utility.report.log.Step.STEP;
import static org.testng.AssertJUnit.assertTrue;
import java.util.Collections;
import com.google.common.collect.ImmutableMap;
import java.util.List;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.v0.service.RMAuditService;
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;
/**
@@ -51,9 +52,10 @@ import org.testng.annotations.Test;
public class AuditUserEventsTests extends BaseRMRestTest
{
private final String PREFIX = generateTestPrefix(AuditUserEventsTests.class);
private UserModel createUser;
@Autowired
private RMAuditService rmAuditService;
private RMAuditAPI rmAuditAPI;
/**
* Given I have created a new user
@@ -64,16 +66,30 @@ public class AuditUserEventsTests extends BaseRMRestTest
*/
@Test
@AlfrescoTest(jira = "RM-6223")
public void createUserEventIsAudited()
public void createUserEventIsAudited() throws Exception
{
rmAuditService.clearAuditLog();
STEP("Create a new user.");
String userName = "auditCreateUser" + PREFIX;
createUser = getDataUser().createUser(userName);
STEP("Check the audit log contains the entry for the created user event.");
rmAuditService.checkAuditLogForEvent(getAdminUser(), CREATE_PERSON, getAdminUser(), userName,
Collections.singletonList(ImmutableMap.of("new", userName, "previous", "", "name", "User Name")));
STEP("Get the list of audit entries for the create person event.");
List<AuditEntry> auditEntries = rmAuditAPI.getRMAuditLog(getAdminUser().getUsername(),
getAdminUser().getPassword(), 100, CREATE_PERSON.event);
STEP("Check the audit log contains only the entries for the created user.");
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().getUsername(), getAdminUser().getPassword());
}
@AfterClass (alwaysRun = true)

View File

@@ -615,6 +615,37 @@ public class BaseRMRestTest extends RestTest
recordCategoryAPI.deleteRecordCategory(recordCategoryId);
}
/**
* Helper method to create a test user with rm role
*
* @param userRole the rm role
* @return the created user model
*/
protected UserModel createUserWithRMRole(String userRole)
{
UserModel rmUser = getDataUser().createRandomTestUser();
getRestAPIFactory().getRMUserAPI().assignRoleToUser(rmUser.getUsername(), userRole);
assertStatusCode(OK);
return rmUser;
}
/**
* Helper method to create a test user with rm role and permissions over the record category
*
* @param userRole the rm role
* @param userPermission the permissions over the record category
* @param recordCategory the category on which user has permissions
* @return the created user model
*/
protected UserModel createUserWithRMRoleAndCategoryPermission(String userRole, RecordCategory recordCategory,
UserPermissions userPermission)
{
UserModel rmUser = createUserWithRMRole(userRole);
getRestAPIFactory().getRMUserAPI().addUserPermission(recordCategory.getId(), rmUser, userPermission);
assertStatusCode(OK);
return rmUser;
}
/**
* Returns search results for the given search term
*
@@ -818,7 +849,7 @@ public class BaseRMRestTest extends RestTest
*/
protected boolean hasAspect(String nodeId, String aspectName) throws Exception
{
return hasAspect(toFileModel(nodeId), aspectName);
return hasAspect(toFileModel(nodeId),aspectName);
}
/**

View File

@@ -107,4 +107,9 @@ public interface TestData
* The default hold reason
*/
String HOLD_REASON = "Active content to be reviewed for the CASE McDermott, FINRA ";
/**
* Frozen aspect
*/
String FROZEN_ASPECT = "rma:frozen";
}

View File

@@ -26,8 +26,6 @@
*/
package org.alfresco.rest.rm.community.files;
import static org.alfresco.rest.rm.community.base.TestData.HOLD_DESCRIPTION;
import static org.alfresco.rest.rm.community.base.TestData.HOLD_REASON;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.TRANSFERS_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
@@ -89,7 +87,7 @@ public class DeclareAndFileDocumentAsRecordTests extends BaseRMRestTest
private final static String INVALID_DESTINATION_PATH_EXC = "Unable to execute create-record action, because the destination path is invalid.";
private final static String DESTINATION_PATH_NOT_RECORD_FOLDER_EXC = "Unable to execute create-record action, because the destination path is not a record folder.";
private final static String CLOSED_RECORD_FOLDER_EXC = "You can't add new items to a closed record folder.";
private final static String HOLD_NAME = getRandomName("holdName");
private final static String HOLD_NAME = "holdName";
private final static String RECORD_FOLDER_NAME_WITH_SPACE = "Folder With Spaces In Name";
private UserModel userFillingPermission, userReadOnlyPermission;
@@ -413,7 +411,8 @@ public class DeclareAndFileDocumentAsRecordTests extends BaseRMRestTest
public void declareAndFileToHeldRecordFolderUsingFilesAPI() throws Exception
{
RecordCategoryChild heldRecordFolder = createFolder(recordCategory.getId(), getRandomName("heldRecordFolder"));
holdsAPI.createHold(getAdminUser().getUsername(), getAdminUser().getPassword(), HOLD_NAME, HOLD_REASON, HOLD_DESCRIPTION);
holdsAPI.createHold(getAdminUser().getUsername(), getAdminUser().getPassword(), HOLD_NAME, "hold reason",
"hold description");
holdsAPI.addItemToHold(getAdminUser().getUsername(), getAdminUser().getPassword(), heldRecordFolder.getId(),
HOLD_NAME);
@@ -464,7 +463,6 @@ public class DeclareAndFileDocumentAsRecordTests extends BaseRMRestTest
public void declareAndFileDocumentAsRecordCleanup()
{
//delete rm items
holdsAPI.deleteHold(getAdminUser().getUsername(), getAdminUser().getPassword(), HOLD_NAME);
deleteRecordCategory(recordCategory.getId());
getRestAPIFactory().getUnfiledRecordFoldersAPI().deleteUnfiledRecordFolder(unfiledContainerFolder.getId());

View File

@@ -26,13 +26,12 @@
*/
package org.alfresco.rest.rm.community.hold;
import static org.alfresco.rest.rm.community.base.TestData.FROZEN_ASPECT;
import static org.alfresco.rest.rm.community.base.TestData.HOLD_DESCRIPTION;
import static org.alfresco.rest.rm.community.base.TestData.HOLD_REASON;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.TRANSFERS_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAspects.FROZEN_ASPECT;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_RECORD_FOLDER_TYPE;
import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_FILING;
import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_READ_RECORDS;
@@ -109,7 +108,7 @@ public class AddToHoldsTests extends BaseRMRestTest
private ContentActions contentActions;
@BeforeClass (alwaysRun = true)
public void preconditionForAddContentToHold()
public void preconditionForAddContentToHold() throws Exception
{
STEP("Create a hold.");
holdNodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser().getUsername(),
@@ -175,7 +174,7 @@ public class AddToHoldsTests extends BaseRMRestTest
* Valid nodes to be added to hold
*/
@DataProvider (name = "validNodesForAddToHold")
public Object[][] getValidNodesForAddToHold()
public Object[][] getValidNodesForAddToHold() throws Exception
{
//create electronic and nonElectronic record in record folder
RecordCategoryChild recordFolder = createCategoryFolderInFilePlan();
@@ -288,7 +287,7 @@ public class AddToHoldsTests extends BaseRMRestTest
users.add(userModel);
STEP("Add the node to the hold with user without permission.");
String response = holdsAPI.addToHoldAndGetMessage(userModel.getUsername(), userModel.getPassword(),
SC_INTERNAL_SERVER_ERROR, nodeToBeAddedToHold, holdNodeRef);
SC_INTERNAL_SERVER_ERROR, nodeToBeAddedToHold, HOLD);
assertTrue(response.contains(ACCESS_DENIED_ERROR_MESSAGE));
STEP("Check the node is not frozen.");
@@ -346,7 +345,7 @@ public class AddToHoldsTests extends BaseRMRestTest
{
STEP("Add the node to the hold ");
String responseErrorMessage = holdsAPI.addToHoldAndGetMessage(getAdminUser().getUsername(),
getAdminUser().getPassword(), responseCode, itemNodeRef, holdNodeRef);
getAdminUser().getPassword(), responseCode, itemNodeRef, HOLD);
assertTrue(responseErrorMessage.contains(errorMessage),
"Actual error message " + responseErrorMessage + " expected " + errorMessage);
@@ -355,7 +354,7 @@ public class AddToHoldsTests extends BaseRMRestTest
}
@AfterClass (alwaysRun = true)
public void cleanUpAddContentToHold()
public void cleanUpAddContentToHold() throws Exception
{
holdsAPI.deleteHold(getAdminUser().getUsername(), getAdminUser().getPassword(), HOLD);
dataSite.usingAdmin().deleteSite(testSite);

View File

@@ -36,7 +36,6 @@ import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
import static org.springframework.http.HttpStatus.OK;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
@@ -160,8 +159,7 @@ public class PreventActionsOnFrozenContentTests extends BaseRMRestTest
restClient.authenticateUser(getAdminUser()).withCoreAPI().usingNode(contentHeld).updateNodeContent(updatedFile);
STEP("Check the request failed.");
//TODO change this to FORBIDDEN when REPO-4632 is fixed
restClient.assertStatusCodeIs(INTERNAL_SERVER_ERROR);
restClient.assertStatusCodeIs(FORBIDDEN);
restClient.assertLastError().containsSummary("Frozen content can't be updated.");
}
@@ -196,7 +194,7 @@ public class PreventActionsOnFrozenContentTests extends BaseRMRestTest
STEP("Check the request failed.");
assertStatusCode(FORBIDDEN);
getRestAPIFactory().getRmRestWrapper().assertLastError().containsSummary("Permission was denied");
getRestAPIFactory().getRmRestWrapper().assertLastError().containsSummary("Frozen nodes can not be copied.");
}
/**

View File

@@ -28,9 +28,9 @@ package org.alfresco.rest.rm.community.hold;
import static java.util.Arrays.asList;
import static org.alfresco.rest.rm.community.base.TestData.FROZEN_ASPECT;
import static org.alfresco.rest.rm.community.base.TestData.HOLD_DESCRIPTION;
import static org.alfresco.rest.rm.community.base.TestData.HOLD_REASON;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAspects.FROZEN_ASPECT;
import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_FILING;
import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_READ_RECORDS;
import static org.alfresco.rest.rm.community.model.user.UserRoles.ROLE_RM_MANAGER;
@@ -95,12 +95,12 @@ public class RemoveFromHoldsTests extends BaseRMRestTest
private RoleService roleService;
@BeforeClass (alwaysRun = true)
public void preconditionForRemoveContentFromHold()
public void preconditionForRemoveContentFromHold() throws Exception
{
STEP("Create two holds.");
holdNodeRefOne = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser().getUsername(),
HOLD_ONE, HOLD_REASON, HOLD_DESCRIPTION);
holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser()
String holdNodeRefTwo = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser()
.getUsername(), HOLD_TWO, HOLD_REASON, HOLD_DESCRIPTION);
STEP("Create test files.");
@@ -265,7 +265,7 @@ public class RemoveFromHoldsTests extends BaseRMRestTest
STEP("Remove node from hold with user without right permission or capability");
String responseNoHoldPermission = holdsAPI.removeFromHoldAndGetMessage(userModel.getUsername(),
userModel.getPassword(), SC_INTERNAL_SERVER_ERROR, nodeIdToBeRemoved, holdNodeRefOne);
userModel.getPassword(), SC_INTERNAL_SERVER_ERROR, nodeIdToBeRemoved, HOLD_ONE);
assertTrue(responseNoHoldPermission.contains(ACCESS_DENIED_ERROR_MESSAGE));
STEP("Check node is frozen.");

View File

@@ -137,10 +137,8 @@ public class RecordFolderTests extends BaseRMRestTest
* Then the operation fails
* </pre>
*/
//TODO enable this test when REPO-2454 is fixed
@Test
(
enabled = false,
description = "Create invalid types as children for a record folder",
dataProvider = "childrenNotAllowedForFolder"
)

View File

@@ -31,7 +31,6 @@ import static org.alfresco.rest.rm.community.base.TestData.NONELECTRONIC_RECORD_
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.TRANSFERS_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAspects.RECORD_SEARCH_ASPECT;
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;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_RECORD_FOLDER_TYPE;
@@ -42,7 +41,7 @@ import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import static org.testng.AssertJUnit.assertTrue;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.record.Record;
@@ -51,11 +50,10 @@ import org.alfresco.rest.rm.community.model.record.RecordContent;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChild;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildProperties;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordFolderAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordsAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledRecordFolderAPI;
import org.alfresco.test.AlfrescoTest;
import org.alfresco.utility.report.Bug;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@@ -69,35 +67,19 @@ import org.testng.annotations.Test;
public class FileRecordsTests extends BaseRMRestTest
{
private UnfiledContainerChild electronicRecord = UnfiledContainerChild.builder()
.name(ELECTRONIC_RECORD_NAME)
.nodeType(CONTENT_TYPE)
.content(RecordContent.builder().mimeType("text/plain").build())
.build();
.name(ELECTRONIC_RECORD_NAME)
.nodeType(CONTENT_TYPE)
.content(RecordContent.builder().mimeType("text/plain").build())
.build();
private UnfiledContainerChild nonelectronicRecord = UnfiledContainerChild.builder()
.properties(UnfiledContainerChildProperties.builder()
.description(NONELECTRONIC_RECORD_NAME)
.title("Title")
.build())
.name(NONELECTRONIC_RECORD_NAME)
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.build();
private String targetFolderId, folderToLink, closedFolderId, unfiledRecordFolderId;
@BeforeClass (alwaysRun = true)
public void setupFileRecordsTests() throws Exception
{
// create 3 record folders and close one of them
targetFolderId = createCategoryFolderInFilePlan().getId();
folderToLink = createCategoryFolderInFilePlan().getId();
closedFolderId = createCategoryFolderInFilePlan().getId();
closeFolder(closedFolderId);
// create one unfiled record folder
unfiledRecordFolderId = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS,
"Unfiled Folder " + getRandomAlphanumeric(), UNFILED_RECORD_FOLDER_TYPE).getId();
}
.properties(UnfiledContainerChildProperties.builder()
.description(NONELECTRONIC_RECORD_NAME)
.title("Title")
.build())
.name(NONELECTRONIC_RECORD_NAME)
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.build();
/**
* Invalid containers where electronic and non-electronic records can be filed
@@ -117,62 +99,65 @@ public class FileRecordsTests extends BaseRMRestTest
}
/**
* Returns the ids of unfiled electronic and non-electronic records from Unfiled Records container
* Given an unfiled record in the root unfiled record container
* And an open record folder
* When I file the unfiled record into the record folder
* Then the record is filed
*/
@DataProvider (name = "unfiledRecordsFromUnfiledRecordsContainer")
public Object[][] getRecordsFromUnfiledRecordsContainer()
@Test
public void fileRecordIntoExistingFolderFromUnfiledContainer() throws Exception
{
// get API instances
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
// create a record folder
String folderId = createCategoryFolderInFilePlan().getId();
// create records
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
UnfiledContainerChild recordElectronic = unfiledContainersAPI.uploadRecord(electronicRecord,
UNFILED_RECORDS_CONTAINER_ALIAS, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME));
UnfiledContainerChild recordElectronic = unfiledContainersAPI.uploadRecord(electronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS,
createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME));
UnfiledContainerChild recordNonElect = unfiledContainersAPI.createUnfiledContainerChild(nonelectronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS);
return new String[][] {
{ recordElectronic.getId()},
{ recordNonElect.getId()}
};
}
/**
* Returns the ids of unfiled electronic and non-electronic records from an Unfiled Record Folder
*/
@DataProvider (name = "unfiledRecordsFromUnfiledRecordFolder")
public Object[][] getRecordsFromUnfiledRecordFolder()
{
UnfiledRecordFolderAPI unfiledRecordFoldersAPI = getRestAPIFactory().getUnfiledRecordFoldersAPI();
UnfiledContainerChild recordElectronic = unfiledRecordFoldersAPI.uploadRecord(electronicRecord, unfiledRecordFolderId,
createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME));
UnfiledContainerChild recordNonElect = unfiledRecordFoldersAPI.createUnfiledRecordFolderChild(nonelectronicRecord, unfiledRecordFolderId);
return new String[][] {
{ recordElectronic.getId()},
{ recordNonElect.getId()}
};
}
/**
* Given an unfiled record in the root unfiled record container
* And an open record folder
* When I file the unfiled record into the record folder
* Then the record is filed
*/
@Test (dataProvider = "unfiledRecordsFromUnfiledRecordsContainer")
@AlfrescoTest (jira = "RM-7060")
public void fileRecordFromUnfiledContainerToOpenFolder(String unfiledRecordId) throws Exception
{
// file the record to the folder created
Record recordFiled = fileRecordToFolder(unfiledRecordId, targetFolderId);
// file the record into the folder created
RecordBodyFile recordBodyFile = RecordBodyFile.builder().targetParentId(folderId).build();
Record recordFiled = recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
// check the response status
assertStatusCode(CREATED);
// check the parent id for the record returned
assertEquals(recordFiled.getParentId(), targetFolderId);
assertEquals(recordFiled.getParentId(),folderId);
// check the record is filed to the record folder
assertTrue(isRecordChildOfRecordFolder(unfiledRecordId, targetFolderId), unfiledRecordId + " is not filed to " + targetFolderId);
// check the record is filed into the record folder
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
assertTrue(recordFolderAPI.getRecordFolderChildren(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordElectronic.getId())));
// check the record doesn't exist into unfiled record container
assertFalse(isRecordChildOfUnfiledContainer(unfiledRecordId), unfiledRecordId + " exists in Unfiled Records");
assertTrue(hasAspect(unfiledRecordId, RECORD_SEARCH_ASPECT), "recordSearch aspect is lost after filing!");
assertFalse(unfiledContainersAPI.getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordElectronic.getId())));
// file the non-electronic record into the folder created
Record nonElectRecordFiled = recordsAPI.fileRecord(recordBodyFile, recordNonElect.getId());
// check the response status code
assertStatusCode(CREATED);
// check the parent id for the record returned
assertEquals(nonElectRecordFiled.getParentId(), folderId);
// check the record is added into the record folder
assertTrue(recordFolderAPI.getRecordFolderChildren(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordNonElect.getId())));
// check the record doesn't exist into unfiled record container
assertFalse(unfiledContainersAPI.getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordNonElect.getId())));
}
/**
@@ -181,24 +166,62 @@ public class FileRecordsTests extends BaseRMRestTest
* When I file the unfiled record into the record folder
* Then the record is filed
*/
@Test (dataProvider = "unfiledRecordsFromUnfiledRecordFolder")
@AlfrescoTest (jira = "RM-7060")
public void fileRecordFromUnfiledRecordFolderToOpenFolder(String unfiledRecordId) throws Exception
@Test
public void fileRecordIntoExistingFolderFromUnfiledRecordFolder() throws Exception
{
// file the record to the folder created
Record recordFiled = fileRecordToFolder(unfiledRecordId, targetFolderId);
// get API instances
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
// create a record folder
String folderId = createCategoryFolderInFilePlan().getId();
// create records
UnfiledRecordFolderAPI unfiledRecordFoldersAPI = getRestAPIFactory().getUnfiledRecordFoldersAPI();
String unfiledRecordFolderId = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, "Unfiled Folder " + getRandomAlphanumeric(), UNFILED_RECORD_FOLDER_TYPE).getId();
UnfiledContainerChild recordElectronic = unfiledRecordFoldersAPI.uploadRecord(electronicRecord, unfiledRecordFolderId, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME));
UnfiledContainerChild recordNonElect = unfiledRecordFoldersAPI.createUnfiledRecordFolderChild(nonelectronicRecord, unfiledRecordFolderId);
// file the record into the folder created
RecordBodyFile recordBodyFile = RecordBodyFile.builder().targetParentId(folderId).build();
Record recordFiled = recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
// check the response status
assertStatusCode(CREATED);
// check the parent id for the record returned
assertEquals(recordFiled.getParentId(), targetFolderId);
assertEquals(recordFiled.getParentId(),folderId);
// check the record is filed to the record folder
assertTrue(isRecordChildOfRecordFolder(unfiledRecordId, targetFolderId), unfiledRecordId + " is not filed to " + targetFolderId);
// check the record is filed into the record folder
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
assertTrue(recordFolderAPI.getRecordFolderChildren(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordElectronic.getId())));
// check the record doesn't exist into unfiled record folder
assertFalse(isRecordChildOfUnfiledRecordFolder(unfiledRecordId),
unfiledRecordId + " exists in " + unfiledRecordFolderId);
assertTrue(hasAspect(unfiledRecordId, RECORD_SEARCH_ASPECT), "recordSearch aspect is lost after filing!");
assertFalse(unfiledRecordFoldersAPI.getUnfiledRecordFolderChildren(unfiledRecordFolderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordElectronic.getId())));
// file the non-electronic record into the folder created
Record nonElectRecordFiled = recordsAPI.fileRecord(recordBodyFile, recordNonElect.getId());
// check the response status code
assertStatusCode(CREATED);
// check the parent id for the record returned
assertEquals(nonElectRecordFiled.getParentId(), folderId);
// check the record is added into the record folder
assertTrue(recordFolderAPI.getRecordFolderChildren(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordNonElect.getId())));
// check the record doesn't exist into unfiled record folder
assertFalse(unfiledRecordFoldersAPI.getUnfiledRecordFolderChildren(unfiledRecordFolderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordNonElect.getId())));
}
/**
@@ -208,42 +231,114 @@ public class FileRecordsTests extends BaseRMRestTest
* Then I get an unsupported operation exception
*
*/
@Test (dataProvider = "unfiledRecordsFromUnfiledRecordsContainer")
public void fileRecordFromUnfiledContainerToClosedFolder(String unfiledRecordId)
@Test
public void fileRecordIntoCloseFolderFromUnfiledContainer() throws Exception
{
// file the record to the closed record folder
fileRecordToFolder(unfiledRecordId, closedFolderId);
// check the response status
assertStatusCode(FORBIDDEN);
// get API instances
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
// check the record is not filed to the record folder
assertFalse(isRecordChildOfRecordFolder(unfiledRecordId, closedFolderId), unfiledRecordId + " is filed to " + closedFolderId);
// create a record folder
String folderId = createCategoryFolderInFilePlan().getId();
closeFolder(folderId);
// create records
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
// check the record exist into unfiled record container
assertTrue(isRecordChildOfUnfiledContainer(unfiledRecordId), unfiledRecordId + " doesn't exist in Unfiled Records");
}
UnfiledContainerChild recordElectronic = unfiledContainersAPI.uploadRecord(electronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME));
UnfiledContainerChild recordNonElect = unfiledContainersAPI.createUnfiledContainerChild(nonelectronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS);
/**
* Given an unfiled record in a unfiled record folder
* And a closed record folder
* When I file the unfiled record into the record folder
* Then I get an unsupported operation exception
*
*/
@Test(dataProvider = "unfiledRecordsFromUnfiledRecordFolder")
public void fileRecordFromUnfiledRecordFolderToClosedFolder(String unfiledRecordId)
{
// file the record into the closed folder created
fileRecordToFolder(unfiledRecordId, closedFolderId);
// file the record into the folder created
RecordBodyFile recordBodyFile = RecordBodyFile.builder().targetParentId(folderId).build();
recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
// check the response status
assertStatusCode(FORBIDDEN);
// check the record is not filed into the record folder
assertFalse(isRecordChildOfRecordFolder(unfiledRecordId, closedFolderId), unfiledRecordId + " is filed to " + closedFolderId);
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
assertFalse(recordFolderAPI.getRecordFolderChildren(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordElectronic.getId())));
// check the record exist into unfiled record container
assertTrue(unfiledContainersAPI.getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordElectronic.getId())));
// file the non-electronic record into the folder created
recordsAPI.fileRecord(recordBodyFile, recordNonElect.getId());
// check the response status code
assertStatusCode(FORBIDDEN);
// check the record is not added into the record folder
assertFalse(recordFolderAPI.getRecordFolderChildren(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordNonElect.getId())));
// check the record exist into unfiled record container
assertTrue(unfiledContainersAPI.getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS)
.getEntries().stream()
.anyMatch(c -> c.getEntry().getId().equals(recordNonElect.getId())));
}
/**
* Given an unfiled record in a unfiled record folder
* And a closed record folder
* When I file the unfiled record into the record folder
* Then I get an unsupported operation exception
*
*/
@Test
public void fileRecordIntoCloseFolderFromUnfiledRecordFolder() throws Exception
{
// get API instances
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
// create a record folder
String folderId = createCategoryFolderInFilePlan().getId();
closeFolder(folderId);
// create records
UnfiledRecordFolderAPI unfiledRecordFoldersAPI = getRestAPIFactory().getUnfiledRecordFoldersAPI();
String unfiledRecordFolderId = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, "Unfiled Folder " + getRandomAlphanumeric(), UNFILED_RECORD_FOLDER_TYPE).getId();
UnfiledContainerChild recordElectronic = unfiledRecordFoldersAPI.uploadRecord(electronicRecord, unfiledRecordFolderId, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME));
UnfiledContainerChild recordNonElect = unfiledRecordFoldersAPI.createUnfiledRecordFolderChild(nonelectronicRecord, unfiledRecordFolderId);
// file the record into the folder created
RecordBodyFile recordBodyFile = RecordBodyFile.builder().targetParentId(folderId).build();
recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
// check the response status
assertStatusCode(FORBIDDEN);
// check the record is not filed into the record folder
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
assertFalse(recordFolderAPI.getRecordFolderChildren(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordElectronic.getId())));
// check the record exist into unfiled record folder
assertTrue(isRecordChildOfUnfiledRecordFolder(unfiledRecordId),
unfiledRecordId + " doesn't exist in " + unfiledRecordFolderId);
assertTrue(unfiledRecordFoldersAPI.getUnfiledRecordFolderChildren(unfiledRecordFolderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordElectronic.getId())));
// file the non-electronic record into the folder created
recordsAPI.fileRecord(recordBodyFile, recordNonElect.getId());
// check the response status code
assertStatusCode(FORBIDDEN);
// check the record is not added into the record folder
assertFalse(recordFolderAPI.getRecordFolderChildren(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordNonElect.getId())));
// check the record exist into unfiled record folder
assertTrue(unfiledRecordFoldersAPI.getUnfiledRecordFolderChildren(unfiledRecordFolderId)
.getEntries().stream()
.anyMatch(c -> c.getEntry().getId().equals(recordNonElect.getId())));
}
/**
@@ -252,34 +347,71 @@ public class FileRecordsTests extends BaseRMRestTest
* When I file the filed record into the record folder
* Then the record is filed in both locations
*/
@Test (dataProvider = "unfiledRecordsFromUnfiledRecordsContainer")
@Bug (id = "RM-4578")
public void linkRecordInto(String unfiledRecordId)
@Test
@Bug(id="RM-4578")
public void linkRecordInto() throws Exception
{
// file the record to the open folder created
Record recordFiled = fileRecordToFolder(unfiledRecordId, targetFolderId);
// get API instances
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
// create a record folder
String parentFolderId = createCategoryFolderInFilePlan().getId();
// create records
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
UnfiledContainerChild recordElectronic = unfiledContainersAPI.uploadRecord(electronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME));
UnfiledContainerChild recordNonElect = unfiledContainersAPI.createUnfiledContainerChild(nonelectronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS);
// file the record into the folder created
RecordBodyFile recordBodyFile = RecordBodyFile.builder().targetParentId(parentFolderId).build();
Record recordFiled = recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
Record nonElectronicFiled = recordsAPI.fileRecord(recordBodyFile, recordNonElect.getId());
// check the response status
assertStatusCode(CREATED);
// link the record to the second folder
Record recordLink = fileRecordToFolder(unfiledRecordId, folderToLink);
// create the second folder
String folderToLink = createCategoryFolderInFilePlan().getId();
recordBodyFile = RecordBodyFile.builder().targetParentId(folderToLink).build();
// check the response status
assertStatusCode(CREATED);
assertTrue(recordLink.getParentId().equals(targetFolderId));
// link the electronic record
Record recordLink = recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
assertTrue(recordLink.getParentId().equals(parentFolderId));
// check the response status code
assertStatusCode(CREATED);
// link the nonelectronic record
Record nonElectronicLink = recordsAPI.fileRecord(recordBodyFile, nonElectronicFiled.getId());
assertStatusCode(CREATED);
assertTrue(nonElectronicLink.getParentId().equals(parentFolderId));
// check the record is added into the record folder
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
assertTrue(recordFolderAPI.getRecordFolderChildren(targetFolderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordFiled.getId()) &&
c.getEntry().getParentId().equals(targetFolderId)));
assertTrue(recordFolderAPI.getRecordFolderChildren(parentFolderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordFiled.getId()) &&
c.getEntry().getParentId().equals(parentFolderId)));
// check the record has a link in the second folder
// check the record doesn't exist into unfiled record container
assertTrue(recordFolderAPI.getRecordFolderChildren(folderToLink)
.getEntries().stream()
.anyMatch(c -> c.getEntry().getId().equals(recordFiled.getId()) &&
c.getEntry().getParentId().equals(targetFolderId) &&
!c.getEntry().getParentId().equals(folderToLink)));
.getEntries().stream()
.anyMatch(c -> c.getEntry().getId().equals(recordFiled.getId()) &&
c.getEntry().getParentId().equals(parentFolderId) &&
!c.getEntry().getParentId().equals(folderToLink)));
// check the record is added into the record folder
assertTrue(recordFolderAPI.getRecordFolderChildren(parentFolderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(nonElectronicFiled.getId()) &&
c.getEntry().getParentId().equals(parentFolderId)));
// check the record doesn't exist into unfiled record container
assertTrue(recordFolderAPI.getRecordFolderChildren(folderToLink)
.getEntries().stream()
.anyMatch(c -> c.getEntry().getId().equals(nonElectronicFiled.getId()) &&
c.getEntry().getParentId().equals(parentFolderId) &&
!c.getEntry().getParentId().equals(folderToLink)));
}
/**
@@ -293,77 +425,24 @@ public class FileRecordsTests extends BaseRMRestTest
dataProvider = "invalidContainersToFile",
description = "File the unfiled record to the container that is not a record folder"
)
public void invalidContainerToFile(String containerId)
public void invalidContainerToFile(String containerId) throws Exception
{
// get API instances
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
// create records
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
UnfiledContainerChild recordElectronic = unfiledContainersAPI.uploadRecord(electronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME));
UnfiledContainerChild recordNonElect = unfiledContainersAPI.createUnfiledContainerChild(nonelectronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS);
// file the records to a container that is not a record folder
fileRecordToFolder(recordElectronic.getId(), containerId);
// file the record into the folder created
RecordBodyFile recordBodyFile = RecordBodyFile.builder().targetParentId(containerId).build();
recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
assertStatusCode(BAD_REQUEST);
fileRecordToFolder(recordNonElect.getId(), containerId);
recordsAPI.fileRecord(recordBodyFile, recordNonElect.getId());
// check the response status
assertStatusCode(BAD_REQUEST);
}
/**
* Files the given record in the target record folder.
*
* @param recordId the id of the record to be filed
* @param targetFolderId the id of the target record folder
*/
private Record fileRecordToFolder(String recordId, String targetFolderId)
{
RecordBodyFile recordBodyFile = RecordBodyFile.builder().targetParentId(targetFolderId).build();
return getRestAPIFactory().getRecordsAPI().fileRecord(recordBodyFile, recordId);
}
/**
* Returns whether any child of the record folder match the provided record
*
* @param recordId the record id
* @param recordFolderId the record folder id
* @return true if any child of the record folder match the provided record, false otherwise
*/
private boolean isRecordChildOfRecordFolder(String recordId, String recordFolderId)
{
return getRestAPIFactory().getRecordFolderAPI()
.getRecordFolderChildren(recordFolderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordId));
}
/**
* Returns whether any child of the unfiled record folder match the provided record
*
* @param recordId the record id
* @return true if any child of the unfiled record folder match the provided record, false otherwise
*/
private boolean isRecordChildOfUnfiledRecordFolder(String recordId)
{
return getRestAPIFactory().getUnfiledRecordFoldersAPI()
.getUnfiledRecordFolderChildren(unfiledRecordFolderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordId));
}
/**
* Returns whether any child of the unfiled container match the provided record
*
* @param recordId the record id
* @return true if any child of the unfiled container match the provided record, false otherwise
*/
private boolean isRecordChildOfUnfiledContainer(String recordId)
{
return getRestAPIFactory().getUnfiledContainersAPI()
.getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordId));
}
}

View File

@@ -1,63 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2020 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.rest.rm.community.records;
import static org.alfresco.rest.rm.community.base.TestData.ELECTRONIC_RECORD_NAME;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAspects.RECORD_SEARCH_ASPECT;
import static org.alfresco.rest.rm.community.utils.CoreUtil.createBodyForMoveCopy;
import static org.alfresco.rest.rm.community.utils.CoreUtil.toContentModel;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.OK;
import static org.testng.Assert.assertTrue;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.test.AlfrescoTest;
import org.testng.annotations.Test;
/**
* Move records tests
*
* @author Claudia Agache
* @since 3.3
*/
public class MoveRecordsTests extends BaseRMRestTest
{
@Test (description = "rma:recordSearch aspect is reapplied after record move")
@AlfrescoTest (jira = "RM-7060")
public void moveRecord() throws Exception
{
String parentFolderId = createCategoryFolderInFilePlan().getId();
String targetFolderId = createCategoryFolderInFilePlan().getId();
String electronicRecordId = createElectronicRecord(parentFolderId, ELECTRONIC_RECORD_NAME).getId();
STEP("Move record from one folder to the other");
getRestAPIFactory().getNodeAPI(toContentModel(electronicRecordId)).move(createBodyForMoveCopy(targetFolderId));
assertStatusCode(OK);
STEP("Check the record still has rma:recordSearch aspect.");
assertTrue(hasAspect(electronicRecordId, RECORD_SEARCH_ASPECT), "recordSearch aspect is lost after move!");
}
}

View File

@@ -1,223 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2020 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.rest.rm.community.search;
import static org.alfresco.rest.rm.community.model.user.UserRoles.ROLE_RM_MANAGER;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
import org.alfresco.dataprep.ContentActions;
import org.alfresco.rest.RestTest;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.user.UserPermissions;
import org.alfresco.rest.v0.service.RoleService;
import org.alfresco.test.AlfrescoTest;
import org.alfresco.utility.Utility;
import org.alfresco.utility.constants.UserRole;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FileType;
import org.alfresco.utility.model.SiteModel;
import org.alfresco.utility.model.UserModel;
import org.apache.chemistry.opencmis.client.api.ItemIterable;
import org.apache.chemistry.opencmis.client.api.OperationContext;
import org.apache.chemistry.opencmis.client.api.QueryResult;
import org.apache.chemistry.opencmis.client.runtime.OperationContextImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* Test to check that RM doesn't break CMIS query
*
* @author jcule, Rodica Sutu
* @since 2.5.4
* @since 3.3
*/
public class CmisQueryTests extends BaseRMRestTest
{
private static final String SEARCH_TERM = generateTestPrefix(CmisQueryTests.class);
private static final String sqlWithName =
"SELECT cmis:name FROM cmis:document where CONTAINS('cmis:name:*" + SEARCH_TERM + "*')";
private SiteModel collaborationSite;
private UserModel nonRMUser, rmUser;
private RecordCategoryChild recordFolder;
@Autowired
private ContentActions contentActions;
@Autowired
private RoleService roleService;
/**
* Create some test data:
* <pre>
* - a collaboration site with documents
* - in place records
* - category with folder and records
* - a user with no rm rights (no rights to see the record from file plan)
* - a user with rights to see the records and the other documents created
* </pre>
*/
@BeforeClass (alwaysRun = true)
public void setupCmisQuery() throws Exception
{
STEP("Create a collaboration site");
collaborationSite = dataSite.usingAdmin().createPrivateRandomSite();
STEP("Create 10 documents ending with SEARCH_TERM");
for (int i = 0; ++i <= 10; )
{
FileModel fileModel = new FileModel(String.format("%s%s%s.%s", "Doc", i, SEARCH_TERM,
FileType.TEXT_PLAIN.extension));
dataContent.usingAdmin().usingSite(collaborationSite).createContent(fileModel);
}
STEP("Create a collaborator user for the collaboration site");
nonRMUser = getDataUser().createRandomTestUser();
getDataUser().addUserToSite(nonRMUser, collaborationSite, UserRole.SiteCollaborator);
STEP("Create 10 documents and declare as records");
for (int i = 0; ++i <= 10; )
{
FileModel fileModel = new FileModel(String.format("%s%s%s.%s", "InPlace ", SEARCH_TERM, i,
FileType.TEXT_PLAIN.extension));
fileModel = dataContent.usingUser(nonRMUser).usingSite(collaborationSite).createContent(fileModel);
getRestAPIFactory().getFilesAPI(nonRMUser).declareAsRecord(fileModel.getNodeRefWithoutVersion());
}
STEP("Create record folder and some records ");
recordFolder = createCategoryFolderInFilePlan();
for (int i = 0; ++i <= 10; )
{
createElectronicRecord(recordFolder.getId(), String.format("%s%s%s.%s", "Record ", SEARCH_TERM, i,
FileType.TEXT_PLAIN.extension));
}
STEP("Create an rm user with read permission over the category created and contributor role within the " +
"collaboration site");
rmUser = roleService.createUserWithSiteRoleRMRoleAndPermission(collaborationSite, UserRole.SiteContributor,
recordFolder.getParentId(), ROLE_RM_MANAGER, UserPermissions.PERMISSION_READ_RECORDS);
//do a cmis query to wait for solr indexing
Utility.sleep(5000, 80000, () ->
{
ItemIterable<QueryResult> results =
contentActions.getCMISSession(getAdminUser().getUsername(), getAdminUser().getPassword()).query(sqlWithName,
false);
assertEquals("Total number of items is not 30, got " + results.getTotalNumItems() + " total items",
30, results.getTotalNumItems());
});
}
/**
* <pre>
* Given the RM site created
* When I execute a cmis query to get all the documents names
* Then I get all documents names 100 per page
* </pre>
*/
@Test
@AlfrescoTest (jira = "MNT-19442")
public void getAllDocumentsNamesCmisQuery()
{
// execute the cmis query
String cq = "SELECT cmis:name FROM cmis:document";
ItemIterable<QueryResult> results =
contentActions.getCMISSession(getAdminUser().getUsername(), getAdminUser().getPassword()).query(cq,
false);
// check the total number of items is greater than 100 and has more items is true
assertTrue("Has more items not true.", results.getHasMoreItems());
assertTrue("Total number of items is not greater than 100. Total number of items received" + results.getTotalNumItems(),
results.getTotalNumItems() > 100);
assertEquals("Expected 100 items per page and got " + results.getPageNumItems() + " per page.", 100,
results.getPageNumItems());
}
/**
* <pre>
* Given the RM site created
* When I execute a cmis query to get all the documents names with a particular name
* Then I get all documents names user has permission
* </pre>
*/
@Test
@AlfrescoTest (jira = "MNT-19442")
public void getDocumentsWithSpecificNamesCmisQuery() throws Exception
{
// execute the cmis query
ItemIterable<QueryResult> results =
contentActions.getCMISSession(nonRMUser.getUsername(), nonRMUser.getPassword()).query(sqlWithName,
false);
assertEquals("Total number of items is not 20, got " + results.getTotalNumItems() + " total items",
20, results.getTotalNumItems());
// check the has more items is false
assertFalse("Has more items not false.", results.getHasMoreItems());
assertEquals("Expected 20 items per page and got " + results.getPageNumItems() + " per page.", 20,
results.getPageNumItems());
}
/**
* <pre>
* Given the RM site created
* When I execute a cmis query to get all the documents names with a specific number per page
* Then I get all documents names paged as requested that the user has permission
* </pre>
*/
@Test
@AlfrescoTest (jira = "MNT-19442")
public void getDocumentsCmisQueryWithPagination() throws Exception
{
OperationContext oc = new OperationContextImpl();
oc.setMaxItemsPerPage(10);
ItemIterable<QueryResult> results =
contentActions.getCMISSession(rmUser.getUsername(), rmUser.getPassword()).query(sqlWithName,
false, oc);
// check the total number of items and has more items is true
assertTrue("Has more items not true. ", results.getHasMoreItems());
assertEquals("Total number of items is not 30, got " + results.getTotalNumItems(), 30,
results.getTotalNumItems());
assertEquals("Expected 10 items per page and got " + results.getPageNumItems() + " per page.",
10, results.getPageNumItems());
}
@AfterClass
private void clearCmisQueryTests()
{
dataSite.usingAdmin().deleteSite(collaborationSite);
getRestAPIFactory().getRecordCategoryAPI().deleteRecordCategory(recordFolder.getParentId());
getDataUser().usingAdmin().deleteUser(rmUser);
getDataUser().usingAdmin().deleteUser(nonRMUser);
}
}

View File

@@ -49,7 +49,6 @@ public class RMSiteUtil
public static final String RM_ID = "rm";
public static final String RM_TITLE = "Records Management";
public static final String RM_DESCRIPTION = "Records Management Site";
public static final String FILE_PLAN_PATH = "/rm/documentLibrary";
/**
* Creates an RM Site model for the given compliance, title and description

View File

@@ -17,7 +17,7 @@ RM is split into two main parts - a repository integration and a Share integrati
### Artifacts and Guidance
* [Community Source Code](https://github.com/Alfresco/records-management)
* [Enterprise Source Code](https://gitlab.alfresco.com/records-management/records-management) (for partners and customers)
* [Enterprise Source Code](https://github.com/Alfresco/governance-services) (for partners and customers)
* [Community License](../LICENSE.txt)
* [Enterprise License](../../rm-enterprise/LICENSE.txt) (this file will only be present in clones of the Enterprise repository)
* [Issue Tracker Link](https://issues.alfresco.com/jira/projects/RM)

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services</artifactId>
<version>3.3.0.1</version>
<version>3.2.0.4</version>
</parent>
<licenses>
@@ -75,9 +75,8 @@
<properties>
<spring.version>5.1.8.RELEASE</spring.version>
<alfresco.version>6.2.0-ga</alfresco.version>
<alfresco.min.version>6.1</alfresco.min.version>
<share.version>6.2.0</share.version>
<alfresco.version>6.1.2-ga</alfresco.version>
<share.version>6.1.0</share.version>
<!-- The properties app.amp.* need to be set for share to work. -->
<app.filtering.enabled>true</app.filtering.enabled>
</properties>

View File

@@ -1,6 +1,3 @@
TRANSFORMERS_TAG=2.1.0
SOLR6_TAG=1.4.0
POSTGRES_TAG=11.4
ACTIVEMQ_TAG=5.15.8
LEGACY_TRANSFORM_SERVICE_ENABLED=true
LOCAL_TRANSFORM_SERVICE_ENABLED=true
SOLR6_TAG=1.1.1
POSTGRES_TAG=10.1
ACTIVEMQ_TAG=5.15.6

View File

@@ -1,9 +1,4 @@
### Apply AGS community repo AMP to ACS image
FROM alfresco/alfresco-content-repository-community:6.2.0-ga
# Alfresco user does not have permissions to modify webapps or configuration. Switch to root.
# The access will be fixed after all operations are done.
USER root
FROM alfresco/alfresco-content-repository-community:6.1.2-ga
COPY target/alfresco-governance-services-community-repo-*.amp /usr/local/tomcat/amps/
@@ -15,13 +10,4 @@ COPY target/gs-api-explorer-*.war /usr/local/tomcat/webapps/
### Unpack gs-api-explorer.war
RUN mkdir /usr/local/tomcat/webapps/gs-api-explorer && cd /usr/local/tomcat/webapps/gs-api-explorer && \
jar -xvf /usr/local/tomcat/webapps/gs-api-explorer-*.war && rm -f /usr/local/tomcat/webapps/gs-api-explorer-*.war
# All files in the tomcat folder must be owned by root user and Alfresco group as mentioned in the parent Dockerfile
RUN chgrp -R Alfresco /usr/local/tomcat && \
find /usr/local/tomcat/webapps -type d -exec chmod 0750 {} \; && \
find /usr/local/tomcat/webapps -type f -exec chmod 0640 {} \; && \
chmod -R g+r /usr/local/tomcat/webapps
# Switching back to alfresco user after having added amps files to run the container as non-root
USER alfresco
jar -xvf /usr/local/tomcat/webapps/gs-api-explorer-*.war && rm -f /usr/local/tomcat/webapps/gs-api-explorer-*.war

View File

@@ -17,14 +17,14 @@ rm.action.no-declare-mand-prop=Um den Record abzuschlie\u00dfen, m\u00fcssen Sie
rm.action.ghosted-prop-update=Die Eigenschaften eines zuvor vernichteten Record k\u00f6nnen nicht aktualisiert werden.
rm.action.valid-date-disp-asof=Geben Sie ein zul\u00e4ssiges Datum als Startdatum der Aufbewahrungsaktion ein.
rm.action.disp-asof-lifecycle-applied=Sie k\u00f6nnen das Startdatum der Aufbewahrung f\u00fcr einen Record oder Record-Ordner mit festgelegtem Aufbewahrungszyklus nicht bearbeiten.
rm.action.hold-edit-reason-none=Der Grund f\u00fcr den Legal Hold kann nicht bearbeitet werden, da er ohne Grund erstellt wurde. Versuchen Sie, den Legal Hold erneut zu erstellen.
rm.action.hold-edit-type=Sie k\u00f6nnen den Grund f\u00fcr den Legal Hold von {1} nicht bearbeiten, da es sich nicht um einen Legal Hold handelt.
rm.action.hold-edit-reason-none=Der Sperrgrund kann nicht bearbeitet werden, da die Sperre ohne Grund erstellt wurde. Versuchen Sie, die Sperre erneut zu erstellen.
rm.action.hold-edit-type=Sie k\u00f6nnen den Sperrgrund f\u00fcr {1} nicht bearbeiten, da es sich nicht um eine Sperre handelt.
rm.action.specify-avlid-date=Geben Sie ein zul\u00e4ssiges Datum als Startdatum der \u00dcberpr\u00fcfung ein.
rm.action.review-details-only=Sie k\u00f6nnen nur die \u00dcberpr\u00fcfungsdetails besonders relevanter Records bearbeiten.
rm.action.freeze-no-reason=Ein Record kann nicht ohne Grund mit einem Legal Hold belegt werden. F\u00fcgen Sie einen Grund f\u00fcr den Legal Hold hinzu.
rm.action.freeze-only-records-folders=Sie k\u00f6nnen nur Records oder Record-Ordner mit einem Legal Hold belegen.
rm.action.freeze-no-reason=Ein Record kann nicht ohne Grund gesperrt werden. F\u00fcgen Sie einen Sperrgrund hinzu.
rm.action.freeze-only-records-folders=Sie k\u00f6nnen nur Records oder Record-Ordner sperren.
rm.action.no-open-record-folder=Sie k\u00f6nnen {0} nicht erneut \u00f6ffnen, da es sich nicht um einen Record-Ordner handelt.
rm.action.not-hold-type=Die Aktion kann nicht f\u00fcr {1} durchgef\u00fchrt werden, weil es sich nicht um einen Legal Hold handelt.
rm.action.not-hold-type=Die Aktion kann nicht f\u00fcr {1} durchgef\u00fchrt werden, weil es sich nicht um eine Sperre handelt.
rm.action.no-read-mime-message=Die Dateityp-Nachricht konnte nicht gelesen werden, da {0}.
rm.action.email-declared=Die E-Mail konnte nicht geteilt werden, da der Record abgeschlossen ist. (actionedUponNodeRef={0})
rm.action.email-not-record=Die E-Mail konnte nicht geteilt werden, da die Datei, der Ordner bzw. die Kategorie kein Record ist. (actionedUponNodeRef={0})
@@ -36,7 +36,7 @@ rm.action.records_only_undeclared=Es k\u00f6nnen nur Records abgeschlossen werde
rm.action.event-not-undone=Sie k\u00f6nnen das Ereignis {0} nicht r\u00fcckg\u00e4ngig machen, da es nicht im Aufbewahrungszyklus definiert ist.
rm.action.node-not-record-category=Sie k\u00f6nnen keinen Aufbewahrungsplan f\u00fcr ({0}) erstellen, da es sich nicht um eine Record-Kategorie handelt.
rm.action.parameter-not-supplied=F\u00fcgen Sie ''{0}'' hinzu, um fortzufahren.
rm.action.delete-not-hold-type=Der Legal Hold konnte nicht gel\u00f6scht werden, da {1} nicht vom Typ {0} ist.
rm.action.delete-not-hold-type=Die Sperre konnte nicht gel\u00f6scht werden, da {1} nicht vom Typ {0} ist.
rm.action.cast-to-rm-type=Ein benutzerdefinierter Ordnertyp kann nicht in einen Records Management Ablageplan hochgeladen werden.
rm.action.record-folder-create=Ein Record-Ordner kann nicht in einem anderen Record-Ordner erstellt werden.
rm.action.unique.child.type-error-message=Sie k\u00f6nnen hier nicht mehrere Elemente dieser Art erstellen.

View File

@@ -14,8 +14,8 @@ isDeclared.title=Record abgeschlossen
isDeclared.description=Record ist abgeschlossen.
# Is on hold
isFrozen.title=Mit Legal Hold belegt
isFrozen.description=Record oder Record-Ordner mit Legal Hold belegt
isFrozen.title=Gesperrt
isFrozen.description=Record oder Record-Ordner ist gesperrt.
# Are filed
isRecordFiled.title=Record abgelegt
@@ -118,11 +118,11 @@ setPropertyValue.title=Wert einer Eigenschaft setzen
setPropertyValue.description=Setzt den Wert einer Eigenschaft
# Edit Hold Reason
editHoldReason.title=Grund f\u00fcr Legal Hold bearbeiten
editHoldReason.description=Bearbeiten Sie den Grund f\u00fcr den Legal Hold
editHoldReason.title=Sperrgrund bearbeiten
editHoldReason.description=Bearbeitet den Sperrgrund
# Relinquish Hold
relinquishHold.title=Legal Hold aufheben
relinquishHold.description=Hebt einen Legal Hold auf
relinquishHold.title=Sperre aufheben
relinquishHold.description=Hebt eine Sperre auf
# Edit Review As Of Date
editReviewAsOfDate.title=Startdatum der \u00dcberpr\u00fcfung bearbeiten
editReviewAsOfDate.description=Bearbeitet das Startdatum der \u00dcberpr\u00fcfung
@@ -184,8 +184,8 @@ addRecordTypes.description=F\u00fcgt ausgew\u00e4hlte Typen zum Record hinzu
fileReport.title=Bericht ablegen
fileReport.description=Bericht ablegen
# Delete Hold
deleteHold.title=Legal Hold l\u00f6schen
deleteHold.description=Legal Hold l\u00f6schen
deleteHold.title=Sperrbereich l\u00f6schen
deleteHold.description=Sperrbereich l\u00f6schen
# Move DM record
move-dm-record.title=Record verschieben
move-dm-record.description=Record verschieben

View File

@@ -13,11 +13,6 @@ rm.audit.linkTo=Link to
rm.audit.moveTo=Move to
rm.audit.copyTo=Copy to
rm.audit.fileTo=File to
rm.audit.createHold=Create Hold
rm.audit.deleteHold=Delete Hold
rm.audit.addToHold=Add To Hold
rm.audit.removeFromHold=Remove From Hold
rm.audit.holdPermission-Error=You don't have permission to view this hold.
rm.audit.audit-start=Audit Start
rm.audit.audit-stop=Audit Stop
rm.audit.audit-clear=Audit Clear

View File

@@ -13,11 +13,6 @@ rm.audit.linkTo=Link zu
rm.audit.moveTo=Verschieben nach
rm.audit.copyTo=Kopieren nach
rm.audit.fileTo=Ablegen unter
rm.audit.createHold=Legal Hold erstellen
rm.audit.deleteHold=Legal Hold l\u00f6schen
rm.audit.addToHold=Zu Legal Hold hinzuf\u00fcgen
rm.audit.removeFromHold=Aus Legal Hold entfernen
rm.audit.holdPermission-Error=Sie haben nicht die n\u00f6tigen Berechtigungen zum Anzeigen dieses Legal Holds.
rm.audit.audit-start=Audit starten
rm.audit.audit-stop=Audit stoppen
rm.audit.audit-clear=Audit l\u00f6schen

View File

@@ -13,11 +13,6 @@ rm.audit.linkTo=Enlace a
rm.audit.moveTo=Mover a
rm.audit.copyTo=Copiar a
rm.audit.fileTo=Archivar en
rm.audit.createHold=Crear bloqueo
rm.audit.deleteHold=Eliminar bloqueo
rm.audit.addToHold=A\u00f1adir a bloqueo
rm.audit.removeFromHold=Eliminar de bloqueo
rm.audit.holdPermission-Error=No tiene permiso para ver este bloqueo.
rm.audit.audit-start=Iniciar auditor\u00eda
rm.audit.audit-stop=Detener auditor\u00eda
rm.audit.audit-clear=Limpiar auditor\u00eda

View File

@@ -13,11 +13,6 @@ rm.audit.linkTo=Lier \u00e0
rm.audit.moveTo=D\u00e9placer vers...
rm.audit.copyTo=Copier vers...
rm.audit.fileTo=Archiver dans
rm.audit.createHold=Cr\u00e9er une suspension
rm.audit.deleteHold=Supprimer la suspension
rm.audit.addToHold=Ajouter \u00e0 la suspension
rm.audit.removeFromHold=Supprimer de la suspension
rm.audit.holdPermission-Error=Vous n'avez pas les droits requis pour afficher cette suspension.
rm.audit.audit-start=Audit d\u00e9marr\u00e9
rm.audit.audit-stop=Audit arr\u00eat\u00e9
rm.audit.audit-clear=Audit supprim\u00e9

View File

@@ -13,11 +13,6 @@ rm.audit.linkTo=Collega a
rm.audit.moveTo=Sposta in
rm.audit.copyTo=Copia in
rm.audit.fileTo=Archivia in
rm.audit.createHold=Crea sospensione
rm.audit.deleteHold=Annulla sospensione
rm.audit.addToHold=Aggiungi a sospensione
rm.audit.removeFromHold=Rimuovi dalla sospensione
rm.audit.holdPermission-Error=Non si dispone del permesso di visualizzare questa sospensione.
rm.audit.audit-start=Avvio audit
rm.audit.audit-stop=Interruzione audit
rm.audit.audit-clear=Cancellazione audit

View File

@@ -13,11 +13,6 @@ rm.audit.linkTo=\u30ea\u30f3\u30af\u5148
rm.audit.moveTo=\u79fb\u52d5\u5148
rm.audit.copyTo=\u30b3\u30d4\u30fc\u5148
rm.audit.fileTo=\u6574\u7406\u4fdd\u7ba1\u5148
rm.audit.createHold=\u30db\u30fc\u30eb\u30c9\u306e\u4f5c\u6210
rm.audit.deleteHold=\u30db\u30fc\u30eb\u30c9\u306e\u524a\u9664
rm.audit.addToHold=\u30db\u30fc\u30eb\u30c9\u306b\u8ffd\u52a0
rm.audit.removeFromHold=\u30db\u30fc\u30eb\u30c9\u304b\u3089\u524a\u9664
rm.audit.holdPermission-Error=\u3053\u306e\u30db\u30fc\u30eb\u30c9\u306e\u8868\u793a\u6a29\u9650\u304c\u3042\u308a\u307e\u305b\u3093\u3002
rm.audit.audit-start=\u76e3\u67fb\u306e\u958b\u59cb
rm.audit.audit-stop=\u76e3\u67fb\u306e\u505c\u6b62
rm.audit.audit-clear=\u76e3\u67fb\u306e\u6d88\u53bb

View File

@@ -13,11 +13,6 @@ rm.audit.linkTo=Koble til
rm.audit.moveTo=Flytt til
rm.audit.copyTo=Kopier til
rm.audit.fileTo=Arkiver i
rm.audit.createHold=Opprett hold
rm.audit.deleteHold=Slett hold
rm.audit.addToHold=Legg til i hold
rm.audit.removeFromHold=Fjern fra hold
rm.audit.holdPermission-Error=Du har ikke tillatelse til \u00e5 vise dette holdet.
rm.audit.audit-start=Revisjonsstart
rm.audit.audit-stop=Revisjonsstopp
rm.audit.audit-clear=Slett revisjon

View File

@@ -13,11 +13,6 @@ rm.audit.linkTo=Koppelen naar
rm.audit.moveTo=Verplaatsen naar
rm.audit.copyTo=Kopi\u00ebren naar
rm.audit.fileTo=Archiveren in
rm.audit.createHold=Wachtstand maken
rm.audit.deleteHold=Wachtstand verwijderen
rm.audit.addToHold=Toevoegen aan wachtstand
rm.audit.removeFromHold=Verwijderen uit wachtstand
rm.audit.holdPermission-Error=U hebt geen rechten voor het weergeven van deze wachtstand.
rm.audit.audit-start=Audit starten
rm.audit.audit-stop=Audit stoppen
rm.audit.audit-clear=Audit wissen

View File

@@ -13,11 +13,6 @@ rm.audit.linkTo=Vincular a
rm.audit.moveTo=Mover para
rm.audit.copyTo=Copiar para
rm.audit.fileTo=Arquivar em
rm.audit.createHold=Criar espera
rm.audit.deleteHold=Excluir espera
rm.audit.addToHold=Adicionar \u00e0 espera
rm.audit.removeFromHold=Remover da espera
rm.audit.holdPermission-Error=Voc\u00ea n\u00e3o tem permiss\u00e3o para visualizar esta espera.
rm.audit.audit-start=In\u00edcio da auditoria
rm.audit.audit-stop=Parada da auditoria
rm.audit.audit-clear=Limpeza de auditoria

View File

@@ -13,11 +13,6 @@ rm.audit.linkTo=\u0421\u0432\u044f\u0437\u0430\u0442\u044c \u0441
rm.audit.moveTo=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432
rm.audit.copyTo=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432
rm.audit.fileTo=\u0421\u0434\u0430\u0442\u044c \u0432 \u0430\u0440\u0445\u0438\u0432
rm.audit.createHold=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443
rm.audit.deleteHold=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443
rm.audit.addToHold=\u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c
rm.audit.removeFromHold=\u0420\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c
rm.audit.holdPermission-Error=\u0423 \u0432\u0430\u0441 \u043d\u0435\u0442 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0430 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u0434\u0430\u043d\u043d\u043e\u0439 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438.
rm.audit.audit-start=\u0417\u0430\u043f\u0443\u0441\u043a \u0430\u0443\u0434\u0438\u0442\u0430
rm.audit.audit-stop=\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0430\u0443\u0434\u0438\u0442\u0430
rm.audit.audit-clear=\u041e\u0447\u0438\u0441\u0442\u043a\u0430 \u0430\u0443\u0434\u0438\u0442\u0430

View File

@@ -13,11 +13,6 @@ rm.audit.linkTo=\u94fe\u63a5\u5230
rm.audit.moveTo=\u79fb\u52a8\u5230
rm.audit.copyTo=\u590d\u5236\u5230
rm.audit.fileTo=\u7acb\u5377\u81f3
rm.audit.createHold=\u521b\u5efa\u4fdd\u5b58
rm.audit.deleteHold=\u5220\u9664\u4fdd\u5b58
rm.audit.addToHold=\u6dfb\u52a0\u81f3\u4fdd\u5b58
rm.audit.removeFromHold=\u89e3\u9664\u4fdd\u5b58
rm.audit.holdPermission-Error=\u60a8\u6ca1\u6709\u6743\u9650\u67e5\u770b\u6b64\u4fdd\u5b58\u3002
rm.audit.audit-start=\u5f00\u59cb\u5ba1\u8ba1
rm.audit.audit-stop=\u505c\u6b62\u5ba1\u8ba1
rm.audit.audit-clear=\u6e05\u9664\u5ba1\u8ba1

View File

@@ -59,16 +59,16 @@ capability.FileTransferReport.title=\u00dcbertragungsbericht ablegen
capability.EndRetention.title=Aufbewahrung beenden
# Hold Controls
capability.group.holdControls.title=Legal-Hold-Steuerung
capability.group.holdControls.title=Sperrsteuerung
capability.ExtendRetentionPeriodOrFreeze.title=Aufbewahrungsfrist verl\u00e4ngern oder fixieren
capability.Unfreeze.title=Fixierung aufheben
capability.ViewUpdateReasonsForFreeze.title=Aktualisierungsgrund f\u00fcr Fixierung anzeigen
capability.CreateHold.title=Legal Hold erstellen
capability.AddToHold.title=Zum Legal Hold hinzuf\u00fcgen
capability.RemoveFromHold.title=Vom Legal Hold entfernen
capability.FileHoldReport.title=Legal-Hold-Bericht ablegen
capability.DeleteHold.title=Legal Hold l\u00f6schen
capability.EditHold.title=Legal Hold bearbeiten
capability.CreateHold.title=Sperrbereich erstellen
capability.AddToHold.title=Zum Sperrbereich hinzuf\u00fcgen
capability.RemoveFromHold.title=Vom Sperrbereich entfernen
capability.FileHoldReport.title=Sperrbericht ablegen
capability.DeleteHold.title=Sperrbereich l\u00f6schen
capability.EditHold.title=Sperrbereich bearbeiten
# Audit
capability.group.audit.title=Audit

View File

@@ -1,10 +1,9 @@
rm.hold.not-hold={0} is not a hold.
rm.hold.add-to-hold-invalid-type={0} isn't a record, a record folder or content. Only records, record folders or content can be added to a hold.
rm.hold.add-to-hold-invalid-type={0} isn't a record, a record folder or active content. Only records, record \
folders or active content can be added to a hold.
rm.hold.add-to-hold-archived-node=Archived content can't be added to a hold.
rm.hold.add-to-hold-locked-node=Locked content can't be added to a hold.
rm.hold.delete-frozen-node=Frozen content can't be deleted.
rm.hold.delete-node-frozen-children=Can't delete folder because it contains frozen content.
rm.hold.move-frozen-node=Frozen content can't be moved.
rm.hold.update-frozen-node=Frozen content can't be updated.
rm.hold.generic-permission-error=Can't delete hold, because you don't have the correct permissions for all the items within the hold.
rm.hold.detailed-permission-error=Can't delete hold, because filing permissions for at least the following items are needed:
rm.hold.update-frozen-node=Frozen content can't be updated.

View File

@@ -1,10 +1,8 @@
rm.hold.not-hold={0} ist kein Legal Hold.
rm.hold.add-to-hold-invalid-type={0} ist kein Record, Record-Ordner oder Inhalt. Nur Records, Record-Ordner und Inhalte k\u00f6nnen zu Legal Holds hinzugef\u00fcgt werden.
rm.hold.add-to-hold-archived-node=Archivierte Inhalte k\u00f6nnen nicht zu einem Legal Hold hinzugef\u00fcgt werden.
rm.hold.add-to-hold-locked-node=Gesperrte Inhalte k\u00f6nnen nicht zu einem Legal Hold hinzugef\u00fcgt werden.
rm.hold.not-hold={0} ist kein Sperrbereich.
rm.hold.add-to-hold-invalid-type={0} ist kein Record, Record-Ordner oder aktiver Inhalt. Nur Records, Record-Ordner und aktive Inhalte k\u00f6nnen zu einer Sperre hinzugef\u00fcgt werden.
rm.hold.add-to-hold-archived-node=Archivierte Inhalte k\u00f6nnen nicht zu einer Sperre hinzugef\u00fcgt werden.
rm.hold.add-to-hold-locked-node=Gesperrte Inhalte k\u00f6nnen nicht zu einer Sperre hinzugef\u00fcgt werden.
rm.hold.delete-frozen-node=Fixierte Inhalte k\u00f6nnen nicht gel\u00f6scht werden.
rm.hold.delete-node-frozen-children=Der Ordner kann nicht gel\u00f6scht werden, weil er fixierte Inhalte enth\u00e4lt.
rm.hold.move-frozen-node=Fixierte Inhalte k\u00f6nnen nicht verschoben werden.
rm.hold.update-frozen-node=Fixierte Inhalte k\u00f6nnen nicht aktualisiert werden.
rm.hold.generic-permission-error=Legal Hold kann nicht gel\u00f6scht werden, weil Sie nicht die n\u00f6tigen Berechtigungen f\u00fcr alle Elemente im Legal Hold haben.
rm.hold.detailed-permission-error=Legal Hold kann nicht gel\u00f6scht werden, weil Sie dazu Ablageberechtigungen f\u00fcr mindestens die folgenden Elemente brauchen:

View File

@@ -1,10 +1,8 @@
rm.hold.not-hold={0} no es un bloqueo.
rm.hold.add-to-hold-invalid-type={0} no es un documento de archivo, una carpeta de documentos de archivo ni un elemento de contenido. Solo los documentos de archivo, las carpetas de documentos de archivo y los elementos de contenido pueden a\u00f1adirse a un bloqueo.
rm.hold.add-to-hold-invalid-type={0} no es un documento de archivo, una carpeta de documentos de archivo ni un contenido activo. Solo los documentos de archivo, las carpetas de documentos de archivo y los contenidos activos pueden a\u00f1adirse a un bloqueo.
rm.hold.add-to-hold-archived-node=El contenido archivado no puede a\u00f1adirse a un bloqueo.
rm.hold.add-to-hold-locked-node=El contenido bloqueado no puede a\u00f1adirse a un bloqueo.
rm.hold.delete-frozen-node=El contenido congelado no puede eliminarse.
rm.hold.delete-node-frozen-children=La carpeta no puede eliminarse porque contiene contenido congelado.
rm.hold.move-frozen-node=El contenido congelado no puede moverse.
rm.hold.update-frozen-node=El contenido congelado no puede actualizarse.
rm.hold.generic-permission-error=El bloqueo no puede eliminarse porque no dispone de los permisos adecuados para todos los elementos del bloqueo.
rm.hold.detailed-permission-error=El bloqueo no puede eliminarse porque es necesario disponer de permisos de archivado para al menos los siguientes elementos:

View File

@@ -1,10 +1,8 @@
rm.hold.not-hold={0} n''est pas une suspension.
rm.hold.add-to-hold-invalid-type={0} n''est pas un document d''archive, un dossier de documents d''archives ou un contenu. Seuls les documents d''archives, dossiers de documents d''archives ou contenus peuvent \u00eatre ajout\u00e9s \u00e0 une suspension.
rm.hold.add-to-hold-invalid-type={0} n''est pas un document d''archives, un dossier d''archives ou un contenu actif. Seuls les documents d''archives, dossiers d''archives ou contenus actifs peuvent \u00eatre ajout\u00e9s \u00e0 une suspension.
rm.hold.add-to-hold-archived-node=Impossible d'ajouter du contenu archiv\u00e9 \u00e0 une suspension.
rm.hold.add-to-hold-locked-node=Impossible d'ajouter du contenu verrouill\u00e9 \u00e0 une suspension.
rm.hold.delete-frozen-node=Impossible de supprimer du contenu gel\u00e9.
rm.hold.delete-node-frozen-children=Impossible de supprimer le dossier car il contient du contenu gel\u00e9.
rm.hold.move-frozen-node=Impossible de d\u00e9placer du contenu gel\u00e9.
rm.hold.update-frozen-node=Impossible de mettre \u00e0 jour du contenu gel\u00e9.
rm.hold.generic-permission-error=Impossible de supprimer la suspension car vous n'avez pas les droits requis pour tous les \u00e9l\u00e9ments qu'elle contient.
rm.hold.detailed-permission-error=Impossible de supprimer la suspension car les droits d'archivage pour les \u00e9l\u00e9ments suivants au moins sont requis\u00a0:

View File

@@ -1,10 +1,8 @@
rm.hold.not-hold={0} non \u00e8 una sospensione.
rm.hold.add-to-hold-invalid-type={0} non \u00e8 un record, una cartella di record o un contenuto. Solo i record, le cartelle dei record o i contenuti possono essere aggiunti a una sospensione.
rm.hold.add-to-hold-invalid-type={0} non \u00e8 un record, una cartella di record o un contenuto attivo. Solo i record, le cartelle di record o i contenuti attivi possono essere aggiunti ad una sospensione.
rm.hold.add-to-hold-archived-node=I contenuti archiviati non possono essere aggiunti ad una sospensione.
rm.hold.add-to-hold-locked-node=I contenuti bloccati non possono essere aggiunti ad una sospensione.
rm.hold.delete-frozen-node=I contenuti congelati non possono essere eliminati.
rm.hold.delete-node-frozen-children=Impossibile eliminare la cartella poich\u00e9 contiene contenuti congelati.
rm.hold.move-frozen-node=I contenuti congelati non possono essere spostati.
rm.hold.update-frozen-node=I contenuti congelati non possono essere aggiornati.
rm.hold.generic-permission-error=Impossibile eliminare la sospensione. Non si possiedono i permessi corretti per tutti gli elementi contenuti nella sospensione.
rm.hold.detailed-permission-error=Impossibile eliminare la sospensione. Sono necessari i permessi di archiviazione per almeno i seguenti elementi:

View File

@@ -1,10 +1,8 @@
rm.hold.not-hold={0} \u306f\u30db\u30fc\u30eb\u30c9\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002
rm.hold.add-to-hold-invalid-type={0} \u306f\u30ec\u30b3\u30fc\u30c9\u3001\u30ec\u30b3\u30fc\u30c9\u30d5\u30a9\u30eb\u30c0\u3001\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u3044\u305a\u308c\u3067\u3082\u3042\u308a\u307e\u305b\u3093\u3002\u30db\u30fc\u30eb\u30c9\u306b\u8ffd\u52a0\u3067\u304d\u308b\u306e\u306f\u30ec\u30b3\u30fc\u30c9\u3001\u30ec\u30b3\u30fc\u30c9\u30d5\u30a9\u30eb\u30c0\u3001\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u307f\u3067\u3059\u3002
rm.hold.add-to-hold-invalid-type={0} \u306f\u30ec\u30b3\u30fc\u30c9\u3001\u30ec\u30b3\u30fc\u30c9\u30d5\u30a9\u30eb\u30c0\u3001\u30a2\u30af\u30c6\u30a3\u30d6\u306a\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u3044\u305a\u308c\u3067\u3082\u3042\u308a\u307e\u305b\u3093\u3002\u30db\u30fc\u30eb\u30c9\u306b\u8ffd\u52a0\u3067\u304d\u308b\u306e\u306f\u30ec\u30b3\u30fc\u30c9\u3001\u30ec\u30b3\u30fc\u30c9\u30d5\u30a9\u30eb\u30c0\u3001\u30a2\u30af\u30c6\u30a3\u30d6\u306a\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u307f\u3067\u3059\u3002
rm.hold.add-to-hold-archived-node=\u30a2\u30fc\u30ab\u30a4\u30d6\u6e08\u307f\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u306f\u30db\u30fc\u30eb\u30c9\u306b\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3002
rm.hold.add-to-hold-locked-node=\u30ed\u30c3\u30af\u3055\u308c\u3066\u3044\u308b\u30b3\u30f3\u30c6\u30f3\u30c4\u306f\u30db\u30fc\u30eb\u30c9\u306b\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3002
rm.hold.delete-frozen-node=\u51cd\u7d50\u3055\u308c\u305f\u30b3\u30f3\u30c6\u30f3\u30c4\u306f\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3002
rm.hold.delete-node-frozen-children=\u30d5\u30a9\u30eb\u30c0\u306b\u51cd\u7d50\u3055\u308c\u305f\u30b3\u30f3\u30c6\u30f3\u30c4\u304c\u542b\u307e\u308c\u3066\u3044\u308b\u305f\u3081\u3001\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3002
rm.hold.move-frozen-node=\u51cd\u7d50\u3055\u308c\u305f\u30b3\u30f3\u30c6\u30f3\u30c4\u306f\u79fb\u52d5\u3067\u304d\u307e\u305b\u3093\u3002
rm.hold.update-frozen-node=\u51cd\u7d50\u3055\u308c\u305f\u30b3\u30f3\u30c6\u30f3\u30c4\u306f\u66f4\u65b0\u3067\u304d\u307e\u305b\u3093\u3002
rm.hold.generic-permission-error=\u30db\u30fc\u30eb\u30c9\u5185\u306e\u3059\u3079\u3066\u306e\u30a2\u30a4\u30c6\u30e0\u306b\u5bfe\u3059\u308b\u9069\u5207\u306a\u6a29\u9650\u304c\u306a\u3044\u305f\u3081\u3001\u30db\u30fc\u30eb\u30c9\u3092\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3002
rm.hold.detailed-permission-error=\u30db\u30fc\u30eb\u30c9\u3092\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3002\u5c11\u306a\u304f\u3068\u3082\u6b21\u306e\u30a2\u30a4\u30c6\u30e0\u306e\u6574\u7406\u4fdd\u7ba1\u6a29\u9650\u304c\u5fc5\u8981\u3067\u3059:

View File

@@ -1,10 +1,8 @@
rm.hold.not-hold={0} er ikke et hold.
rm.hold.add-to-hold-invalid-type={0} er ikke en oppf\u00f8ring, en oppf\u00f8ringsmappe eller innhold. Kun oppf\u00f8ringer, oppf\u00f8ringsmapper eller innhold kan legges til i et hold.
rm.hold.add-to-hold-archived-node=Arkivert innhold kan ikke legges til et hold.
rm.hold.add-to-hold-locked-node=L\u00e5st innhold kan ikke legges til et hold.
rm.hold.not-hold={0} er ikke en hold.
rm.hold.add-to-hold-invalid-type={0} er ikke en oppf\u00f8ring, en oppf\u00f8ringsmappe eller aktivt innhold. Kun oppf\u00f8ringer, oppf\u00f8ringsmapper eller aktivt innhold kan legges til i en hold.
rm.hold.add-to-hold-archived-node=Arkivert innhold kan ikke legges til en hold.
rm.hold.add-to-hold-locked-node=L\u00e5st innhold kan ikke legges til en hold.
rm.hold.delete-frozen-node=Frosset innhold kan ikke slettes.
rm.hold.delete-node-frozen-children=Kan ikke slette mappen fordi den inneholder frosset innhold.
rm.hold.move-frozen-node=Frosset innhold kan ikke flyttes.
rm.hold.update-frozen-node=Frosset innhold kan ikke oppdateres.
rm.hold.generic-permission-error=Kan ikke slette holdet, da du ikke har de riktige tillatelsene for alle elementene i holdet.
rm.hold.detailed-permission-error=Kan ikke slette holdet, fordi arkiveringstillatelser for minst f\u00f8lgende elementer er n\u00f8dvendig:

View File

@@ -1,10 +1,8 @@
rm.hold.not-hold={0} is geen wachtstand.
rm.hold.add-to-hold-invalid-type={0} is geen record, archiefmap of content. Alleen records, archiefmappen of content kunnen worden toegevoegd aan een wachtstand.
rm.hold.add-to-hold-invalid-type={0} is geen record, recordmap of actieve content. Alleen records, recordmappen of actieve content kunnen worden toegevoegd aan een wachtstand.
rm.hold.add-to-hold-archived-node=Gearchiveerde content kan niet worden toegevoegd aan een wachtstand.
rm.hold.add-to-hold-locked-node=Vergrendelde content kan niet worden toegevoegd aan een wachtstand.
rm.hold.delete-frozen-node=Geblokkeerde content kan niet worden verwijderd.
rm.hold.delete-node-frozen-children=De map kan niet worden verwijderd omdat deze geblokkeerde content bevat.
rm.hold.move-frozen-node=Geblokkeerde content kan niet worden verplaatst.
rm.hold.update-frozen-node=Geblokkeerde content kan niet worden bijgewerkt.
rm.hold.generic-permission-error=Kan wachtstand niet verwijderen, omdat u niet beschikt over de juiste rechten voor alle onderdelen in de wachtstand.
rm.hold.detailed-permission-error=Kan wachtstand niet verwijderen, omdat er alleen al voor de volgende onderdelen archiveringsrechten nodig zijn:

View File

@@ -1,10 +1,8 @@
rm.hold.not-hold={0} n\u00e3o \u00e9 uma espera.
rm.hold.add-to-hold-invalid-type={0} n\u00e3o \u00e9 um documento arquiv\u00edstico, uma pasta de documento arquiv\u00edstico ou conte\u00fado. Somente documentos arquiv\u00edsticos, pastas de documentos arquiv\u00edsticos ou conte\u00fados podem ser adicionados a uma espera.
rm.hold.add-to-hold-invalid-type={0} n\u00e3o \u00e9 um documento arquiv\u00edstico, uma pasta de documento arquiv\u00edstico ou conte\u00fado ativo. Somente documentos arquiv\u00edsticos, pastas de documentos arquiv\u00edsticos ou conte\u00fados ativos podem ser adicionados a uma espera.
rm.hold.add-to-hold-archived-node=Conte\u00fado arquivado n\u00e3o pode ser adicionado a uma espera.
rm.hold.add-to-hold-locked-node=Conte\u00fado bloqueado n\u00e3o pode ser adicionado a uma espera.
rm.hold.delete-frozen-node=Conte\u00fado congelado n\u00e3o pode ser exclu\u00eddo.
rm.hold.delete-node-frozen-children=N\u00e3o \u00e9 poss\u00edvel excluir a pasta pois ela cont\u00e9m conte\u00fado congelado.
rm.hold.move-frozen-node=Conte\u00fado congelado n\u00e3o pode ser movido.
rm.hold.update-frozen-node=Conte\u00fado congelado n\u00e3o pode ser atualizado.
rm.hold.generic-permission-error=N\u00e3o \u00e9 poss\u00edvel excluir a espera porque voc\u00ea n\u00e3o tem as permiss\u00f5es corretas para todos os itens na espera.
rm.hold.detailed-permission-error=N\u00e3o \u00e9 poss\u00edvel excluir a espera porque s\u00e3o necess\u00e1rias permiss\u00f5es de arquivamento para os itens a seguir, no m\u00ednimo:

View File

@@ -1,10 +1,8 @@
rm.hold.not-hold={0} \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u043e\u0439.
rm.hold.add-to-hold-invalid-type={0} \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0438\u0441\u044c\u044e, \u043f\u0430\u043f\u043a\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0438\u043b\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c. \u0422\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u043f\u0438\u0441\u0438, \u043f\u0430\u043f\u043a\u0438 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0438\u043b\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u044b.
rm.hold.add-to-hold-invalid-type={0} \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0438\u0441\u044c\u044e, \u043f\u0430\u043f\u043a\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0438\u043b\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c. \u0422\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u043f\u0438\u0441\u0438, \u043f\u0430\u043f\u043a\u0438 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0438\u043b\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0432 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443.
rm.hold.add-to-hold-archived-node=\u0410\u0440\u0445\u0438\u0432\u043d\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0432 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443.
rm.hold.add-to-hold-locked-node=\u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0432 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443.
rm.hold.delete-frozen-node=\u0417\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u043e.
rm.hold.delete-node-frozen-children=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043f\u0430\u043f\u043a\u0443, \u0442. \u043a. \u0432 \u043d\u0435\u0439 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435.
rm.hold.move-frozen-node=\u0417\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u043e.
rm.hold.update-frozen-node=\u0417\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043e.
rm.hold.generic-permission-error=\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0443 \u0432\u0430\u0441 \u043d\u0435\u0442 \u043d\u0443\u0436\u043d\u044b\u0445 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432.
rm.hold.detailed-permission-error=\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0434\u043b\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f:

View File

@@ -1,10 +1,8 @@
rm.hold.not-hold={0} \u4e0d\u662f\u4fdd\u5b58\u3002
rm.hold.add-to-hold-invalid-type={0} \u4e0d\u662f\u8bb0\u5f55\u3001\u8bb0\u5f55\u6587\u4ef6\u5939\u6216\u5185\u5bb9\u3002\u53ea\u6709\u8bb0\u5f55\u3001\u8bb0\u5f55\u6587\u4ef6\u5939\u6216\u5185\u5bb9\u53ef\u4ee5\u6dfb\u52a0\u5230\u4fdd\u5b58\u4e2d\u3002
rm.hold.add-to-hold-invalid-type={0} \u4e0d\u662f\u8bb0\u5f55\u3001\u8bb0\u5f55\u6587\u4ef6\u5939\u6216\u6d3b\u52a8\u5185\u5bb9\u3002\u53ea\u6709\u8bb0\u5f55\u3001\u8bb0\u5f55\u6587\u4ef6\u5939\u6216\u6d3b\u52a8\u5185\u5bb9\u53ef\u4ee5\u6dfb\u52a0\u5230\u4fdd\u5b58\u4e2d\u3002
rm.hold.add-to-hold-archived-node=\u5df2\u5b58\u6863\u5185\u5bb9\u65e0\u6cd5\u6dfb\u52a0\u5230\u4fdd\u5b58\u4e2d\u3002
rm.hold.add-to-hold-locked-node=\u9501\u5b9a\u5185\u5bb9\u65e0\u6cd5\u6dfb\u52a0\u5230\u4fdd\u5b58\u4e2d\u3002
rm.hold.delete-frozen-node=\u65e0\u6cd5\u5220\u9664\u5df2\u5173\u95ed\u5185\u5bb9\u3002
rm.hold.delete-node-frozen-children=\u65e0\u6cd5\u5220\u9664\u6587\u4ef6\u5939\uff0c\u56e0\u4e3a\u5176\u5305\u542b\u5df2\u5173\u95ed\u5185\u5bb9\u3002
rm.hold.move-frozen-node=\u65e0\u6cd5\u79fb\u52a8\u5df2\u5173\u95ed\u5185\u5bb9\u3002
rm.hold.update-frozen-node=\u65e0\u6cd5\u66f4\u65b0\u5df2\u5173\u95ed\u5185\u5bb9\u3002
rm.hold.generic-permission-error=\u65e0\u6cd5\u5220\u9664\u4fdd\u5b58\uff0c\u56e0\u4e3a\u60a8\u5bf9\u4fdd\u5b58\u4e2d\u7684\u6240\u6709\u9879\u76ee\u6ca1\u6709\u9002\u5f53\u6743\u9650\u3002
rm.hold.detailed-permission-error=\u65e0\u6cd5\u5220\u9664\u4fdd\u5b58\uff0c\u56e0\u4e3a\u81f3\u5c11\u9700\u8981\u4ee5\u4e0b\u9879\u76ee\u7684\u5f52\u6863\u6743\u9650\uff1a

View File

@@ -1,7 +1,7 @@
rm.service.error-add-content-container=Records k\u00f6nnen nur in einem Record-Ordner abgelegt werden.
rm.service.update-disposition-action-def=Sie k\u00f6nnen die Definition der Aufbewahrungsaktion nicht aktualisieren, da \u00c4nderungen am Aufbewahrungsplan gespeichert werden. Versuchen Sie es in ein paar Minuten erneut.
rm.service.set-id=Sie k\u00f6nnen die ID von {0} nicht \u00e4ndern (schreibgesch\u00fctzt).
rm.service.path-node=''{0}'' wurde nicht gefunden. Aktualisieren Sie Ihren Browser, um es noch einmal zu versuchen, oder kontakten Sie Ihre IT-Abteilung.
rm.service.path-node=''{0}'' wurde nicht gefunden. Aktualisieren Sie Ihren Browser, um es noch einmal zu versuchen, oder kontaktieren Sie Ihre IT-Abteilung.
rm.service.invalid-rm-node=Der Records-Management-Node ist ung\u00fcltig, da der Aspekt {0} nicht vorhanden ist.
rm.service.no-root=Records Management Root wurde nicht gefunden. Versuchen Sie, den Record erneut abzulegen.
rm.service.dup-root=Sie k\u00f6nnen hier keinen Ablageplan erstellen, da bereits einer in dieser Ordnerhierarchie erstellt wurde.

View File

@@ -104,12 +104,12 @@ rma_recordsmanagement.property.rma_eventExecutionCompletedBy.decription=Ereignis
rma_recordsmanagement.property.rma_eventExecutionCompletedAt.title=Ereignis abgeschlossen um
rma_recordsmanagement.property.rma_eventExecutionCompletedAt.decription=Ereignis abgeschlossen um
rma_recordsmanagement.type.rma_hold.title=Legal Hold
rma_recordsmanagement.type.rma_hold.decription=Legal Hold
rma_recordsmanagement.property.rma_holdReason.title=Grund f\u00fcr Legal Hold
rma_recordsmanagement.property.rma_holdReason.decription=Grund f\u00fcr Legal Hold
rma_recordsmanagement.association.rma_frozenRecords.title=Records mit Legal Hold
rma_recordsmanagement.association.rma_frozenRecords.decription=Records mit Legal Hold
rma_recordsmanagement.type.rma_hold.title=Sperrbereich
rma_recordsmanagement.type.rma_hold.decription=Sperrbereich
rma_recordsmanagement.property.rma_holdReason.title=Sperrgrund
rma_recordsmanagement.property.rma_holdReason.decription=Sperrgrund
rma_recordsmanagement.association.rma_frozenRecords.title=Gesperrte Records
rma_recordsmanagement.association.rma_frozenRecords.decription=Gesperrte Records
rma_recordsmanagement.type.rma_transfer.title=\u00dcbertragen
rma_recordsmanagement.type.rma_transfer.decription=\u00dcbertragen
@@ -129,8 +129,8 @@ rma_recordsmanagement.property.rma_rootNodeRef.decription=Root-Node
rma_recordsmanagement.aspect.rma_recordsManagementRoot.title=Records Management Root
rma_recordsmanagement.aspect.rma_recordsManagementRoot.decription=Records Management Root
rma_recordsmanagement.association.rma_holds.title=Legal Holds
rma_recordsmanagement.association.rma_holds.decription=Legal Holds
rma_recordsmanagement.association.rma_holds.title=Sperren
rma_recordsmanagement.association.rma_holds.decription=Sperren
rma_recordsmanagement.association.rma_transfers.title=\u00dcbertragungen
rma_recordsmanagement.association.rma_transfers.decription=\u00dcbertragungen
@@ -198,12 +198,12 @@ rma_recordsmanagement.aspect.rma_transferred.decription=\u00dcbertragen
rma_recordsmanagement.aspect.rma_ascended.title=In Archiv aufgenommen
rma_recordsmanagement.aspect.rma_ascended.decription=In Archiv aufgenommen
rma_recordsmanagement.aspect.rma_frozen.title=Mit Legal Hold belegt
rma_recordsmanagement.aspect.rma_frozen.decription=Mit Legal Hold belegt
rma_recordsmanagement.property.rma_frozenAt.title=Legal Hold in
rma_recordsmanagement.property.rma_frozenAt.decription=Legal Hold in
rma_recordsmanagement.property.rma_frozenBy.title=Legal Hold von
rma_recordsmanagement.property.rma_frozenBy.decription=Legal Hold von
rma_recordsmanagement.aspect.rma_frozen.title=Gesperrt
rma_recordsmanagement.aspect.rma_frozen.decription=Gesperrt
rma_recordsmanagement.property.rma_frozenAt.title=Gehalten in
rma_recordsmanagement.property.rma_frozenAt.decription=Gehalten in
rma_recordsmanagement.property.rma_frozenBy.title=Gehalten von
rma_recordsmanagement.property.rma_frozenBy.decription=Gehalten von
rma_recordsmanagement.aspect.rma_caveatConfigRoot.title=Root von Caveat-Konfiguration
rma_recordsmanagement.aspect.rma_caveatConfigRoot.decription=Root von Caveat-Konfiguration
@@ -235,8 +235,8 @@ rma_recordsmanagement.property.rma_recordSearchDispositionAuthority.title=Aufbew
rma_recordsmanagement.property.rma_recordSearchDispositionAuthority.description=Aufbewahrungs-Authority
rma_recordsmanagement.property.rma_recordSearchDispositionInstructions.title=Aufbewahrungsanweisungen
rma_recordsmanagement.property.rma_recordSearchDispositionInstructions.description=Aufbewahrungsanweisungen
rma_recordsmanagement.property.rma_recordSearchHoldReason.title=Grund f\u00fcr Legal Hold
rma_recordsmanagement.property.rma_recordSearchHoldReason.description=Grund f\u00fcr Legal Hold
rma_recordsmanagement.property.rma_recordSearchHoldReason.title=Sperrgrund
rma_recordsmanagement.property.rma_recordSearchHoldReason.description=Sperrgrund
rma_recordsmanagement.property.rma_recordSearchVitalRecordReviewPeriod.title=\u00dcberpr\u00fcfungszeitraum f\u00fcr besonders relevante Records
rma_recordsmanagement.property.rma_recordSearchVitalRecordReviewPeriod.description=\u00dcberpr\u00fcfungszeitraum f\u00fcr besonders relevante Records
rma_recordsmanagement.property.rma_recordSearchVitalRecordReviewPeriodExpression.title=Ausdruck f\u00fcr \u00dcberpr\u00fcfungszeitraum

View File

@@ -9,5 +9,5 @@ rmr_recordsmanagementreport.type.rmr_destructionReport.description=Records Manag
rmr_recordsmanagementreport.type.rmr_destructionReport.title=Vernichtungsprotokoll
rmr_recordsmanagementreport.type.rmr_destructionReport.description=Records Management Vernichtungsprotokoll.
rmr_recordsmanagementreport.type.rmr_holdReport.title=Legal-Hold-Bericht
rmr_recordsmanagementreport.type.rmr_holdReport.description=Records Management-Legal-Hold-Bericht.
rmr_recordsmanagementreport.type.rmr_holdReport.title=Sperrbericht
rmr_recordsmanagementreport.type.rmr_holdReport.description=Records Management Sperrbericht.

View File

@@ -1,4 +1,4 @@
rm.hold.name=Legal Hold
rm.hold.name=Sperrbereich
## Default roles
rm.role.extendedReaders=An Originalposition lesen
@@ -21,5 +21,5 @@ rm.savedsearch.transferRecordsName=Zur \u00dcbertragung geeignete Records und Re
rm.savedsearch.transferRecordsDesc=Alle aktuell zur \u00dcbertragung geeigneten Records und Record-Ordner.
rm.savedsearch.destructionRecordsName=Zur Vernichtung geeignete Records und Record-Ordner
rm.savedsearch.destructionRecordsDesc=Alle aktuell zur Vernichtung geeigneten Records.
rm.savedsearch.frozenRecordsName=Records und Record-Ordner mit Legal Hold
rm.savedsearch.frozenRecordsDesc=Alle derzeit mit einem Legal Hold belegten Records und Record-Ordner.
rm.savedsearch.frozenRecordsName=Gesperrte Records und Record-Ordner
rm.savedsearch.frozenRecordsDesc=Alle derzeit gesperrten Records und Record-Ordner.

View File

@@ -18,10 +18,10 @@ file.report.record=Record
file.report.record.folder=Record-Ordner
file.report.unique.folder.identifier=Eindeutige Ordner-ID
file.report.unique.record.identifier=Eindeutige Record-ID
file.report.hold.report=Legal-Hold-Bericht
file.report.hold.name=Name des Legal Holds
file.report.hold.description=Beschreibung des Legal Holds
file.report.hold.reason=Grund f\u00fcr Legal Hold
file.report.hold.held=Mit Legal Hold belegt
file.report.hold.report=Sperrbericht
file.report.hold.name=Sperrname
file.report.hold.description=Sperrbeschreibung
file.report.hold.reason=Sperrgrund
file.report.hold.held=Gesperrt
file.report.createdby=Erstellt von
file.report.createdon=Erstellt am

View File

@@ -732,10 +732,6 @@
<title>Saved search</title>
</aspect>
<aspect name="rma:dispositionProcessed">
<title>Disposition processed</title>
</aspect>
<aspect name="rma:vitalRecordDefinition">
<title>Vital Record Definition</title>
<properties>

View File

@@ -16,5 +16,5 @@
<property name="filePlanService" ref="filePlanService"/>
<property name="nodeService" ref="nodeService"/>
</bean>
</beans>

View File

@@ -19,7 +19,7 @@
<property name="nodeService" ref="nodeService" />
</bean>
<bean id="rm.holdReportUpdatePatch"
<bean id="rm.holdHoldReportUpdatePatch"
parent="rm.parentModulePatch"
class="org.alfresco.module.org_alfresco_module_rm.patch.v32.RMv32HoldReportUpdatePatch">
<property name="description" value="Update template for generating hold report"/>

View File

@@ -1,19 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- RM v3.3 Patches -->
<bean id="rm.holdAuditValuesUpdatedPatch"
parent="rm.parentModulePatch"
class="org.alfresco.module.org_alfresco_module_rm.patch.v33.RMv33HoldAuditEntryValuesPatch">
<property name="description"
value="Change values for addToHold and removeFromHold audit entries to match updated values for these entries" />
<property name="fixesFromSchema" value="2400" />
<property name="fixesToSchema" value="3201" />
<property name="targetSchema" value="3300" />
<property name="recordsManagementQueryDAO" ref="recordsManagementQueryDAO" />
</bean>
</beans>

View File

@@ -3,30 +3,16 @@
<mapper namespace="alfresco.query.rm">
<parameterMap id="parameter_CountRMIndentifier" type="map">
<parameter property="qnameId" jdbcType="BIGINT" javaType="java.lang.Long"/>
<parameter property="idValue" jdbcType="BIGINT" javaType="java.lang.String"/>
</parameterMap>
<parameterMap id="parameter_CountRMIndentifier" type="map">
<parameter property="qnameId" jdbcType="BIGINT" javaType="java.lang.Long"/>
<parameter property="idValue" jdbcType="BIGINT" javaType="java.lang.String"/>
</parameterMap>
<parameterMap id="parameter_folderPatchPaging" type="map">
<parameter property="processed" jdbcType="BIGINT" javaType="java.lang.Long"/>
<parameter property="folderQnameId" jdbcType="BIGINT" javaType="java.lang.Long"/>
<parameter property="start" jdbcType="BIGINT" javaType="java.lang.Long"/>
<parameter property="end" jdbcType="BIGINT" javaType="java.lang.Long"/>
</parameterMap>
<resultMap id="result_NodeRefEntity" type="org.alfresco.module.org_alfresco_module_rm.query.NodeRefEntity">
<result property="row" column="row" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="protocol" column="protocol" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="identifier" column="identifier" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="uuid" column="uuid" jdbcType="VARCHAR" javaType="java.lang.String"/>
</resultMap>
<resultMap id="result_NodeIds" type="java.lang.Long">
<result property="node.id" column="node_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
</resultMap>
<select id="select_CountRMIndentifier" parameterMap="parameter_CountRMIndentifier" resultType="java.lang.Integer">
<resultMap id="result_NodeIds" type="java.lang.Long">
<result property="node.id" column="node_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
</resultMap>
<select id="select_CountRMIndentifier" parameterMap="parameter_CountRMIndentifier" resultType="java.lang.Integer">
select
count(*)
from
@@ -35,7 +21,7 @@
where
prop.qname_id = ? and
prop.string_value = ?
</select>
<!-- Get distinct property values of children for a given property qname -->
@@ -53,10 +39,10 @@
</select>
<!-- Get list of node ids which reference given content url -->
<select id="select_NodeIdsWhichReferenceContentUrl"
parameterType="ContentUrl"
resultMap="result_NodeIds">
<!-- Get list of node ids which reference given content url -->
<select id="select_NodeIdsWhichReferenceContentUrl"
parameterType="ContentUrl"
resultMap="result_NodeIds">
select
p.node_id
from
@@ -69,42 +55,5 @@
</select>
<select id="select_RecordFoldersWithSchedules"
parameterMap="parameter_folderPatchPaging"
resultMap="result_NodeRefEntity">
select alfn.id , alfs.protocol, alfs.identifier, alfn.uuid
from alf_node alfn, alf_store alfs
where alfn.id not in (
select node_id
from alf_node_aspects
where qname_id = ? )
and type_qname_id = ?
and alfn.store_id = alfs.id
and alfn.id between ? and ?
</select>
<!-- Get a property string value entity -->
<select id="select_PropertyStringValue"
parameterType="org.alfresco.repo.domain.propval.PropertyStringValueEntity"
resultType="org.alfresco.repo.domain.propval.PropertyStringValueEntity">
select id,
string_value as stringValue,
string_end_lower as stringEndLower,
string_crc as stringCrc
from alf_prop_string_value
where string_value = #{stringValue}
and string_end_lower = #{stringEndLower}
and string_crc = #{stringCrc}
</select>
<!-- Update a property string value entity -->
<update id="update_PropertyStringValue"
parameterType="org.alfresco.repo.domain.propval.PropertyStringValueEntity">
update alf_prop_string_value
set string_value = #{stringValue},
string_end_lower = #{stringEndLower},
string_crc = #{stringCrc}
where id = #{id}
</update>
</mapper>
</mapper>

View File

@@ -1024,7 +1024,7 @@
</bean>
<bean id="deleteHold" class="org.alfresco.module.org_alfresco_module_rm.action.impl.DeleteHoldAction" parent="rmAction">
<property name="auditable" value="false"/>
<property name="auditedImmediately" value="true"/>
</bean>
<bean id="deleteHold_proxy" parent="rmProxyAction" >

View File

@@ -12,16 +12,13 @@
<property name="nodeService" ref="nodeService" />
<property name="filePlanService" ref="filePlanService" />
<property name="filePlanRoleService" ref="filePlanRoleService" />
<property name="dictionaryService" ref="DictionaryService" />
</bean>
<bean id="org_alfresco_module_rm_namePathExtractor" class="org.alfresco.module.org_alfresco_module_rm.audit.extractor.NamePathDataExtractor">
<bean id="org_alfresco_module_rm_namePathExtractor" class="org.alfresco.module.org_alfresco_module_rm.audit.extractor.FilePlanNamePathDataExtractor">
<property name="registry" ref="auditModel.extractorRegistry" />
<property name="nodeService" ref="nodeService" />
<property name="filePlanService" ref="filePlanService" />
<property name="ruleService" ref="RuleService" />
<property name="permissionService" ref="PermissionService" />
<property name="dictionaryService" ref="DictionaryService" />
</bean>
<bean id="org_alfresco_module_rm_nodeRefPathExtractor" class="org.alfresco.module.org_alfresco_module_rm.audit.extractor.FilePlanNodeRefPathDataExtractor">
@@ -130,28 +127,4 @@
<property name="label" value="recordable-version-config"/>
</bean>
<bean id="audit-event.createHold" parent="audit-event" class="org.alfresco.module.org_alfresco_module_rm.audit.event.CreateHoldAuditEvent">
<property name="nodeService" ref="nodeService" />
<property name="name" value="Create Hold"/>
<property name="label" value="rm.audit.createHold"/>
</bean>
<bean id="audit-event.deleteHold" parent="audit-event" class="org.alfresco.module.org_alfresco_module_rm.audit.event.DeleteHoldAuditEvent">
<property name="nodeService" ref="nodeService" />
<property name="name" value="Delete Hold"/>
<property name="label" value="rm.audit.deleteHold"/>
</bean>
<bean id="audit-event.addToHold" parent="audit-event" class="org.alfresco.module.org_alfresco_module_rm.audit.event.AddToHoldAuditEvent">
<property name="nodeService" ref="nodeService" />
<property name="name" value="Add To Hold"/>
<property name="label" value="rm.audit.addToHold"/>
</bean>
<bean id="audit-event.removeFromHold" parent="audit-event" class="org.alfresco.module.org_alfresco_module_rm.audit.event.RemoveFromHoldAuditEvent">
<property name="nodeService" ref="nodeService" />
<property name="name" value="Remove From Hold"/>
<property name="label" value="rm.audit.removeFromHold"/>
</bean>
</beans>

View File

@@ -177,11 +177,6 @@
</bean>
<util:constant id="propThumbnailModification" static-field="org.alfresco.model.ContentModel.PROP_LAST_THUMBNAIL_MODIFICATION_DATA" />
<!-- Defines a list of namespace URIs for properties, which should be always editable for a frozen node-->
<util:list id="frozen_alwaysEditURIs" value-type="java.lang.String">
<value>http://www.alfresco.org/model/system/1.0</value>
</util:list>
<bean name="updateFrozenPropertyCheck"
class="org.alfresco.module.org_alfresco_module_rm.util.PropertyModificationAllowedCheck">
@@ -190,7 +185,6 @@
<ref bean="propThumbnailModification" />
</list>
</property>
<property name="editableURIs" ref="frozen_alwaysEditURIs" />
</bean>
<bean id="rma.vitalRecordDefinition" class="org.alfresco.module.org_alfresco_module_rm.model.rma.aspect.VitalRecordDefinitionAspect" parent="rm.baseBehaviour">

View File

@@ -940,8 +940,6 @@
<property name="filePlanService" ref="FilePlanService" />
<property name="namespaceService" ref="NamespaceService" />
<property name="capabilityService" ref="CapabilityService" />
<property name="permissionService" ref="PermissionService" />
<property name="holdService" ref="HoldService" />
<property name="ignoredAuditProperties">
<list>
<value>cm:lastThumbnailModification</value>
@@ -1534,8 +1532,8 @@
<property name="recordService" ref="RecordService" />
<property name="recordFolderService" ref="RecordFolderService" />
<property name="permissionService" ref="PermissionService"/>
<property name="recordsManagementAuditService" ref="RecordsManagementAuditService" />
<property name="capabilityService" ref="CapabilityService"/>
<property name="policyComponent" ref="policyComponent"/>
</bean>
<bean id="HoldService"

View File

@@ -630,6 +630,7 @@
<!-- Abstract parent bean for many POST and PUT Hold beans -->
<bean id="rmBaseHold" parent="webscript" abstract="true">
<property name="holdService" ref="HoldService" />
<property name="recordService" ref="RecordService" />
<property name="recordFolderService" ref="RecordFolderService" />
<property name="nodeService" ref="NodeService" />
<property name="nodeTypeUtility" ref="nodeTypeUtility" />
@@ -680,21 +681,4 @@
parent="rmBaseWebscript">
<property name="relationshipService" ref="RelationshipService" />
</bean>
<!-- Update record schedule GET webscript -->
<bean id="webscript.org.alfresco.repository.schedules.rm-updaterecordschedule.get"
class="org.alfresco.repo.web.scripts.schedule.UpdateRecordScheduleGet"
parent="webscript">
<property name="nodeDAO" ref="nodeDAO"/>
<property name="qnameDAO" ref="qnameDAO"/>
<property name="nodeService" ref="nodeService"/>
<property name="transactionService" ref="transactionService"/>
<property name="dispositionService" ref="dispositionService"/>
<property name="recordService" ref="recordService"/>
<property name="recordsManagementQueryDAO" ref="recordsManagementQueryDAO"/>
<property name="behaviourFilter" ref="policyBehaviourFilter" />
<property name="frozenAspect" ref="rma.freeze"/>
<property name="recordsManagementSearchBehaviour" ref="recordsManagementSearchBehaviour"/>
</bean>
</beans>

View File

@@ -38,7 +38,7 @@ rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getChildByName
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getChildrenByName=RM.Read.0,AFTER_RM.FilterNode
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getPrimaryParent=RM.Read.0
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.createAssociation=RM.Assoc.0.1
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.removeAssociation=RM.Assoc.0.1
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.removeAssociation=Assoc.0.1
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getTargetAssocs=RM.Read.0
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getSourceAssocs=RM.Read.0
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getAssoc=RM.Read.0

View File

@@ -1,3 +1,3 @@
# RM Schema number
version.rm.schema=3300
version.rm.schema=3201

View File

@@ -1,13 +0,0 @@
<webscript>
<shortname>Updates Record Schedules based on Hierarchical Retention Instructions</shortname>
<description><![CDATA[
Updates records schedules by reviewing retention instructions defined within the principle hierarchy.<br/>
URL parameter maxRecordFolders is optional, and represents the maximum number of record folders that should be processed. If not specified maxRecordFolders will be set to the max value for an integer.<br/>
URL parameter recordFolder is optional, and represents the nodeRef of a record folder whose records should be processed. If specified then maxRecordFolders will be ignored.<br/>
]]>
</description>
<url>/api/rm/rm-updateRecordSchedule?maxRecordFolders={maxRecordFolders?}&amp;recordFolder={recordFolder?}</url>
<format default="json">argument</format>
<authentication>admin</authentication>
<transaction allow="readonly">required</transaction>
</webscript>

View File

@@ -1,30 +0,0 @@
<#--
#%L
Alfresco Records Management Module
%%
Copyright (C) 2005 - 2020 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%
-->
{
"responsestatus" : "${responsestatus?json_string}",
"message" : "${message?json_string}"
}

View File

@@ -22,71 +22,21 @@ services:
-Dindex.subsystem.name=solr6
-Dalfresco.restApi.basicAuthScheme=true
-Dimap.server.enabled=true
-Dimap.server.port=1143
-Dftp.enabled=true
-Dftp.port=1221
-Dftp.dataPortFrom=30000
-Dftp.dataPortTo=30099
-Dshare.host=localhost
-Daos.baseUrlOverwrite=http://localhost:8080/alfresco/aos
-Dmessaging.broker.url=\"failover:(tcp://activemq:61616)?timeout=3000&jms.useCompression=true\"
-Dlocal.transform.service.enabled=${LOCAL_TRANSFORM_SERVICE_ENABLED}
-DlocalTransform.pdfrenderer.url=http://alfresco-pdf-renderer:8090/
-DlocalTransform.imagemagick.url=http://imagemagick:8090/
-DlocalTransform.libreoffice.url=http://libreoffice:8090/
-DlocalTransform.tika.url=http://tika:8090/
-DlocalTransform.misc.url=http://transform-misc:8090/
-Dlegacy.transform.service.enabled=${LEGACY_TRANSFORM_SERVICE_ENABLED}
-Dalfresco-pdf-renderer.url=http://alfresco-pdf-renderer:8090/
-Djodconverter.url=http://libreoffice:8090/
-Dimg.url=http://imagemagick:8090/
-Dtika.url=http://tika:8090/
-Dtransform.misc.url=http://transform-misc:8090/
"
ports:
- 8080:8080
- 8000:8000
- 1143:1143
- "21:1221"
- 445:445
- 143:143
- "21:21"
- "30000-30099:30000-30099"
alfresco-pdf-renderer:
image: alfresco/alfresco-pdf-renderer:${TRANSFORMERS_TAG}
environment:
JAVA_OPTS: " -Xms256m -Xmx256m"
ports:
- 8090:8090
imagemagick:
image: alfresco/alfresco-imagemagick:${TRANSFORMERS_TAG}
environment:
JAVA_OPTS: " -Xms256m -Xmx256m"
ports:
- 8091:8090
libreoffice:
image: alfresco/alfresco-libreoffice:${TRANSFORMERS_TAG}
environment:
JAVA_OPTS: " -Xms256m -Xmx256m"
ports:
- 8092:8090
tika:
image: alfresco/alfresco-tika:${TRANSFORMERS_TAG}
environment:
JAVA_OPTS: " -Xms256m -Xmx256m"
ports:
- 8093:8090
transform-misc:
image: alfresco/alfresco-transform-misc:${TRANSFORMERS_TAG}
environment:
JAVA_OPTS: " -Xms256m -Xmx256m"
ports:
- 8094:8090
postgres:
image: library/postgres:${POSTGRES_TAG}
environment:
@@ -107,8 +57,6 @@ services:
- SOLR_SOLR_PORT=8983
#Create the default alfresco and archive cores
- SOLR_CREATE_ALFRESCO_DEFAULTS=alfresco,archive
#HTTP by default
- ALFRESCO_SECURE_COMMS=none
ports:
- 8083:8983 #Browser port

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community</artifactId>
<version>3.3.0.1</version>
<version>3.2.0.4</version>
</parent>
<properties>
@@ -24,11 +24,11 @@
<alfresco.repo.artifactId>alfresco-platform</alfresco.repo.artifactId>
<alfresco.postgres.version>9.1-901.jdbc4</alfresco.postgres.version>
<ags.artifactId>alfresco-governance-services-community-repo</ags.artifactId>
<!-- 6.2.0-ga changes -->
<dependency.alfresco-core.version>7.22</dependency.alfresco-core.version>
<dependency.alfresco-repository.version>7.134.1</dependency.alfresco-repository.version>
<dependency.alfresco-remote-api.version>7.107.1</dependency.alfresco-remote-api.version>
<alfresco.alfresco-share-services.version>6.2.0</alfresco.alfresco-share-services.version>
<!-- 6.1.2-ga changes -->
<dependency.alfresco-core.version>7.5.1</dependency.alfresco-core.version>
<dependency.alfresco-repository.version>7.33.12</dependency.alfresco-repository.version>
<dependency.alfresco-remote-api.version>7.34.1</dependency.alfresco-remote-api.version>
<alfresco.alfresco-share-services.version>6.1.0</alfresco.alfresco-share-services.version>
<image.name>alfresco/alfresco-governance-repository-community</image.name>
<maven.javadoc.skip>false</maven.javadoc.skip>

View File

@@ -27,7 +27,7 @@
package org.alfresco.module.org_alfresco_module_rm.caveat;
import static org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace;
import static org.apache.commons.lang.exception.ExceptionUtils.getFullStackTrace;
import java.io.File;
import java.io.InputStream;
@@ -44,7 +44,6 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import net.sf.acegisecurity.AccessDeniedException;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.caveat.RMListOfValuesConstraint.MatchLogic;
@@ -82,6 +81,8 @@ import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.json.JSONObject;
import net.sf.acegisecurity.AccessDeniedException;
/**
* RM Caveat Config component impl
*
@@ -1041,7 +1042,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon
sb.append("' to the JSONObject 'listMembers' '");
sb.append(listMembers);
sb.append("': ");
sb.append(getStackTrace(error));
sb.append(getFullStackTrace(error));
throw new AlfrescoRuntimeException(sb.toString());
}
}
@@ -1060,7 +1061,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon
sb.append("' to the JSONObject 'configJSONObject' '");
sb.append(configJSONObject);
sb.append("': ");
sb.append(getStackTrace(error));
sb.append(getFullStackTrace(error));
throw new AlfrescoRuntimeException(sb.toString());
}
}

View File

@@ -39,7 +39,7 @@ import org.alfresco.service.cmr.dictionary.ConstraintException;
import org.alfresco.service.cmr.i18n.MessageLookup;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.repository.datatype.TypeConversionException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.extensions.surf.util.I18NUtil;
/**

View File

@@ -36,7 +36,7 @@ import java.util.Map;
import java.util.Set;
import org.alfresco.service.cmr.security.AuthorityService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;

View File

@@ -27,7 +27,7 @@
package org.alfresco.module.org_alfresco_module_rm.action;
import static org.apache.commons.lang3.StringUtils.leftPad;
import static org.apache.commons.lang.StringUtils.leftPad;
import java.io.Serializable;
import java.util.HashSet;
@@ -683,7 +683,7 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe
*
* @return padded string or the original if already at &gt;= len characters
*
* @deprecated As of 2.1, replaced by {@link org.apache.commons.lang3.StringUtils#leftPad(String, int)}
* @deprecated As of 2.1, replaced by {@link org.apache.commons.lang.StringUtils#leftPad(String, int)}
*/
@Deprecated
protected String padString(String s, int len)

View File

@@ -37,7 +37,7 @@ import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

View File

@@ -43,7 +43,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.version.Version;
import org.alfresco.service.namespace.QName;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang.StringUtils;
/**
* Destroy action.

View File

@@ -31,7 +31,7 @@ import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.extensions.surf.util.I18NUtil;
/**

View File

@@ -42,7 +42,7 @@ import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.namespace.QName;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.extensions.surf.util.I18NUtil;
/**

View File

@@ -45,7 +45,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.namespace.QName;
import org.alfresco.workflow.RMWorkflowModel;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

View File

@@ -27,7 +27,7 @@
package org.alfresco.module.org_alfresco_module_rm.action.impl;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang.StringUtils.isBlank;
import java.io.IOException;
import java.io.InputStream;

View File

@@ -33,7 +33,6 @@ import static org.alfresco.model.ContentModel.PROP_USERNAME;
import static org.alfresco.module.org_alfresco_module_rm.audit.event.UserGroupMembershipUtils.PARENT_GROUP;
import static org.alfresco.module.org_alfresco_module_rm.dod5015.DOD5015Model.TYPE_DOD_5015_SITE;
import static org.alfresco.module.org_alfresco_module_rm.model.rma.type.RmSiteType.DEFAULT_SITE_NAME;
import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4;
import static org.apache.commons.lang3.StringUtils.isBlank;
import java.io.BufferedWriter;
@@ -61,8 +60,6 @@ import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction
import org.alfresco.module.org_alfresco_module_rm.audit.event.AuditEvent;
import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService;
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
import org.alfresco.module.org_alfresco_module_rm.hold.HoldService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.audit.AuditComponent;
import org.alfresco.repo.audit.model.AuditApplication;
import org.alfresco.repo.content.MimetypeMap;
@@ -84,7 +81,6 @@ import org.alfresco.service.cmr.repository.MLText;
import org.alfresco.service.cmr.repository.NodeRef;
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.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.namespace.NamespaceService;
@@ -95,7 +91,8 @@ import org.alfresco.util.PropertyCheck;
import org.alfresco.util.PropertyMap;
import org.alfresco.util.TempFileProvider;
import org.alfresco.util.transaction.TransactionListenerAdapter;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
@@ -139,7 +136,6 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
protected static final String RM_AUDIT_SNIPPET_CHANGES = "/changes";
protected static final String RM_AUDIT_SNIPPET_BEFORE = "/before";
protected static final String RM_AUDIT_SNIPPET_AFTER = "/after";
protected static final String RM_AUDIT_SITES_PATH = "/Sites";
protected static final String RM_AUDIT_DATA_PERSON_FULLNAME = "/RM/event/person/fullName";
protected static final String RM_AUDIT_DATA_PERSON_ROLES = "/RM/event/person/roles";
@@ -197,10 +193,6 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
private static final String AUDIT_EVENT_VIEW = "audit.view";
private static final String MSG_AUDIT_VIEW = "rm.audit.audit-view";
private static final QName PROPERTY_HOLD_NAME = QName.createQName(RecordsManagementModel.RM_URI, "Hold Name");
private static final QName PROPERTY_HOLD_NODEREF = QName.createQName(RecordsManagementModel.RM_URI, "Hold NodeRef");
private static final String HOLD_PERMISSION_DENIED_MSG = "rm.audit.holdPermission-Error";
private PolicyComponent policyComponent;
private DictionaryService dictionaryService;
private TransactionService transactionService;
@@ -213,8 +205,6 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
private FilePlanService filePlanService;
private NamespaceService namespaceService;
protected CapabilityService capabilityService;
protected PermissionService permissionService;
protected HoldService holdService;
private boolean shutdown = false;
@@ -331,24 +321,6 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
this.ignoredAuditProperties = ignoredAuditProperties;
}
/**
*
* @param permissionService
*/
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
/**
*
* @param holdService
*/
public void setHoldService(HoldService holdService)
{
this.holdService = holdService;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService#registerAuditEvent(java.lang.String, java.lang.String)
*/
@@ -703,8 +675,7 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
/**
* Helper method to remove system properties from maps
*
* @param before properties before event
* @param after properties after event
* @param properties
*/
private void removeAuditProperties(Map<QName, Serializable> before, Map<QName, Serializable> after)
{
@@ -881,7 +852,219 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
}
// define the callback
AuditQueryCallback callback = new AuditTrailQueryCallback(results, writer, reportFormat);
AuditQueryCallback callback = new AuditQueryCallback()
{
private boolean firstEntry = true;
@Override
public boolean valuesRequired()
{
return true;
}
/**
* Just log the error, but continue
*/
@Override
public boolean handleAuditEntryError(Long entryId, String errorMsg, Throwable error)
{
logger.warn(errorMsg, error);
return true;
}
@Override
@SuppressWarnings("unchecked")
public boolean handleAuditEntry(
Long entryId,
String applicationName,
String user,
long time,
Map<String, Serializable> values)
{
// Check for context shutdown
if (shutdown)
{
return false;
}
Date timestamp = new Date(time);
String eventName = null;
String fullName = null;
String userRoles = null;
NodeRef nodeRef = null;
String nodeName = null;
String nodeType = null;
String nodeIdentifier = null;
String namePath = null;
Map<QName, Serializable> beforeProperties = null;
Map<QName, Serializable> afterProperties = null;
if (values.containsKey(RM_AUDIT_DATA_EVENT_NAME))
{
// This data is /RM/event/...
eventName = (String) values.get(RM_AUDIT_DATA_EVENT_NAME);
fullName = (String) values.get(RM_AUDIT_DATA_PERSON_FULLNAME);
userRoles = (String) values.get(RM_AUDIT_DATA_PERSON_ROLES);
nodeRef = (NodeRef) values.get(RM_AUDIT_DATA_NODE_NODEREF);
nodeName = (String) values.get(RM_AUDIT_DATA_NODE_NAME);
QName nodeTypeQname = (QName) values.get(RM_AUDIT_DATA_NODE_TYPE);
nodeIdentifier = (String) values.get(RM_AUDIT_DATA_NODE_IDENTIFIER);
namePath = (String) values.get(RM_AUDIT_DATA_NODE_NAMEPATH);
beforeProperties = (Map<QName, Serializable>) values.get(RM_AUDIT_DATA_NODE_CHANGES_BEFORE);
afterProperties = (Map<QName, Serializable>) values.get(RM_AUDIT_DATA_NODE_CHANGES_AFTER);
// Convert some of the values to recognizable forms
nodeType = null;
if (nodeTypeQname != null)
{
TypeDefinition typeDef = dictionaryService.getType(nodeTypeQname);
nodeType = (typeDef != null) ? typeDef.getTitle(dictionaryService) : null;
}
}
else if (values.containsKey(DOD5015_AUDIT_DATA_EVENT_NAME))
{
// This data is /RM/event/...
eventName = (String) values.get(DOD5015_AUDIT_DATA_EVENT_NAME);
fullName = (String) values.get(DOD5015_AUDIT_DATA_PERSON_FULLNAME);
userRoles = (String) values.get(DOD5015_AUDIT_DATA_PERSON_ROLES);
nodeRef = (NodeRef) values.get(DOD5015_AUDIT_DATA_NODE_NODEREF);
nodeName = (String) values.get(DOD5015_AUDIT_DATA_NODE_NAME);
QName nodeTypeQname = (QName) values.get(DOD5015_AUDIT_DATA_NODE_TYPE);
nodeIdentifier = (String) values.get(DOD5015_AUDIT_DATA_NODE_IDENTIFIER);
namePath = (String) values.get(DOD5015_AUDIT_DATA_NODE_NAMEPATH);
beforeProperties = (Map<QName, Serializable>) values.get( DOD5015_AUDIT_DATA_NODE_CHANGES_BEFORE);
afterProperties = (Map<QName, Serializable>) values.get(DOD5015_AUDIT_DATA_NODE_CHANGES_AFTER);
// Convert some of the values to recognizable forms
nodeType = null;
if (nodeTypeQname != null)
{
TypeDefinition typeDef = dictionaryService.getType(nodeTypeQname);
nodeType = (typeDef != null) ? typeDef.getTitle(dictionaryService) : null;
}
}
else if (values.containsKey(RM_AUDIT_DATA_LOGIN_USERNAME))
{
user = (String) values.get(RM_AUDIT_DATA_LOGIN_USERNAME);
if (values.containsKey(RM_AUDIT_DATA_LOGIN_ERROR))
{
eventName = RM_AUDIT_EVENT_LOGIN_FAILURE;
// The user didn't log in
fullName = user;
}
else
{
eventName = RM_AUDIT_EVENT_LOGIN_SUCCESS;
fullName = (String) values.get(RM_AUDIT_DATA_LOGIN_FULLNAME);
}
}
else if (values.containsKey(DOD5015_AUDIT_DATA_LOGIN_USERNAME))
{
user = (String) values.get(DOD5015_AUDIT_DATA_LOGIN_USERNAME);
if (values.containsKey(DOD5015_AUDIT_DATA_LOGIN_ERROR))
{
eventName = RM_AUDIT_EVENT_LOGIN_FAILURE;
// The user didn't log in
fullName = user;
}
else
{
eventName = RM_AUDIT_EVENT_LOGIN_SUCCESS;
fullName = (String) values.get(DOD5015_AUDIT_DATA_LOGIN_FULLNAME);
}
}
else
{
// This is not recognisable data
logger.warn(
"Unable to process audit entry for RM. Unexpected data: \n" +
" Entry: " + entryId + "\n" +
" Data: " + values);
// Skip it
return true;
}
if (nodeRef != null && nodeService.exists(nodeRef) &&
filePlanService.isFilePlanComponent(nodeRef) &&
!AccessStatus.ALLOWED.equals(
capabilityService.getCapabilityAccessState(nodeRef, ACCESS_AUDIT_CAPABILITY)))
{
return true;
}
// TODO: Refactor this to use the builder pattern
RecordsManagementAuditEntry entry = new RecordsManagementAuditEntry(
timestamp,
user,
fullName,
// A concatenated string of roles
userRoles,
nodeRef,
nodeName,
nodeType,
eventName,
nodeIdentifier,
namePath,
beforeProperties,
afterProperties);
// write out the entry to the file in requested format
writeEntryToFile(entry);
if (results != null)
{
results.add(entry);
}
if (logger.isDebugEnabled())
{
logger.debug(" " + entry);
}
// Keep going
return true;
}
private void writeEntryToFile(RecordsManagementAuditEntry entry)
{
if (writer == null)
{
return;
}
try
{
if (!firstEntry)
{
if (reportFormat == ReportFormat.HTML)
{
writer.write("\n");
}
else
{
writer.write(",");
}
}
else
{
firstEntry = false;
}
// write the entry to the file
if (reportFormat == ReportFormat.JSON)
{
writer.write("\n\t\t");
}
writeAuditTrailEntry(writer, entry, reportFormat);
}
catch (IOException ioe)
{
throw new AlfrescoRuntimeException(MSG_TRAIL_FILE_FAIL, ioe);
}
}
};
String user = params.getUser();
Long fromTime = getFromDateTime(params.getDateFrom());
@@ -978,7 +1161,7 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
/**
* Gets the start of the from date
* @see org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditServiceImpl#getStartOfDay(java.util.Date)
* @see org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditServiceImpl.getStartOfDay()
*
* @param date The date for which the start should be retrieved.
* @return Returns null if the given date is null, otherwise the start of the given day.
@@ -1020,7 +1203,7 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
/**
* Gets the end of the from date
* @see org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditServiceImpl#getEndOfDay(java.util.Date)
* @see org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditServiceImpl.getEndOfDay()
*
* @param date The date for which the end should be retrieved.
* @return Returns null if the given date is null, otherwise the end of the given day.
@@ -1160,29 +1343,29 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
writer.write("<span class=\"label\">From:</span>");
writer.write("<span class=\"value\">");
Date from = params.getDateFrom();
writer.write(from == null ? "&lt;Not Set&gt;" : escapeHtml4(from.toString()));
writer.write(from == null ? "&lt;Not Set&gt;" : StringEscapeUtils.escapeHtml(from.toString()));
writer.write("</span>");
writer.write("<span class=\"label\">To:</span>");
writer.write("<span class=\"value\">");
Date to = params.getDateTo();
writer.write(to == null ? "&lt;Not Set&gt;" : escapeHtml4(to.toString()));
writer.write(to == null ? "&lt;Not Set&gt;" : StringEscapeUtils.escapeHtml(to.toString()));
writer.write("</span>");
writer.write("<span class=\"label\">Property:</span>");
writer.write("<span class=\"value\">");
QName prop = params.getProperty();
writer.write(prop == null ? "All" : escapeHtml4(getPropertyLabel(prop)));
writer.write(prop == null ? "All" : StringEscapeUtils.escapeHtml(getPropertyLabel(prop)));
writer.write("</span>");
writer.write("<span class=\"label\">User:</span>");
writer.write("<span class=\"value\">");
writer.write(params.getUser() == null ? "All" : escapeHtml4(params.getUser()));
writer.write(params.getUser() == null ? "All" : StringEscapeUtils.escapeHtml(params.getUser()));
writer.write("</span>");
writer.write("<span class=\"label\">Event:</span>");
writer.write("<span class=\"value\">");
writer.write(params.getEvent() == null ? "All" : escapeHtml4(getAuditEventLabel(params.getEvent())));
writer.write(params.getEvent() == null ? "All" : StringEscapeUtils.escapeHtml(getAuditEventLabel(params.getEvent())));
writer.write("</span>\n");
writer.write("</div>\n");
@@ -1224,26 +1407,26 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
writer.write("<div class=\"audit-entry-header\">");
writer.write("<span class=\"label\">Timestamp:</span>");
writer.write("<span class=\"value\">");
writer.write(escapeHtml4(entry.getTimestamp().toString()));
writer.write(StringEscapeUtils.escapeHtml(entry.getTimestamp().toString()));
writer.write("</span>");
writer.write("<span class=\"label\">User:</span>");
writer.write("<span class=\"value\">");
writer.write(entry.getFullName() != null ?
escapeHtml4(entry.getFullName()) :
escapeHtml4(entry.getUserName()));
StringEscapeUtils.escapeHtml(entry.getFullName()) :
StringEscapeUtils.escapeHtml(entry.getUserName()));
writer.write("</span>");
if (entry.getUserRole() != null && entry.getUserRole().length() > 0)
{
writer.write("<span class=\"label\">Role:</span>");
writer.write("<span class=\"value\">");
writer.write(escapeHtml4(entry.getUserRole()));
writer.write(StringEscapeUtils.escapeHtml(entry.getUserRole()));
writer.write("</span>");
}
if (entry.getEvent() != null && entry.getEvent().length() > 0)
{
writer.write("<span class=\"label\">Event:</span>");
writer.write("<span class=\"value\">");
writer.write(escapeHtml4(getAuditEventLabel(entry.getEvent())));
writer.write(StringEscapeUtils.escapeHtml(getAuditEventLabel(entry.getEvent())));
writer.write("</span>\n");
}
writer.write("</div>\n");
@@ -1252,39 +1435,35 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
{
writer.write("<span class=\"label\">Identifier:</span>");
writer.write("<span class=\"value\">");
writer.write(escapeHtml4(entry.getIdentifier()));
writer.write(StringEscapeUtils.escapeHtml(entry.getIdentifier()));
writer.write("</span>");
}
if (entry.getNodeType() != null && entry.getNodeType().length() > 0)
{
writer.write("<span class=\"label\">Type:</span>");
writer.write("<span class=\"value\">");
writer.write(escapeHtml4(entry.getNodeType()));
writer.write(StringEscapeUtils.escapeHtml(entry.getNodeType()));
writer.write("</span>");
}
if (entry.getPath() != null && entry.getPath().length() > 0)
{
// we need to strip off the first part of the path
String path = entry.getPath();
String displayPath;
int idx = path.indexOf(RM_AUDIT_SITES_PATH);
String displayPath = path;
int idx = path.indexOf('/', 1);
if (idx != -1)
{
displayPath = path.substring(idx + RM_AUDIT_SITES_PATH.length());
}
else
{
displayPath = path;
displayPath = "/File Plan" + path.substring(idx);
}
writer.write("<span class=\"label\">Location:</span>");
writer.write("<span class=\"value\">");
writer.write(escapeHtml4(displayPath));
writer.write(StringEscapeUtils.escapeHtml(displayPath));
writer.write("</span>");
}
writer.write("</div>\n");
if (entry.getChangedProperties() != null && !entry.getChangedProperties().isEmpty())
if (entry.getChangedProperties() != null)
{
writer.write("<table class=\"changed-values-table\" cellspacing=\"0\">");
writer.write("<tr><th>Property</th><th>Previous Value</th><th>New Value</th></tr>");
@@ -1307,17 +1486,17 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
if(DataTypeDefinition.MLTEXT.equals(propDataType))
{
writer.write(values.getFirst() == null ? "&lt;none&gt;" : escapeHtml4(convertToMlText((Map) values.getFirst()).getDefaultValue()));
writer.write(values.getFirst() == null ? "&lt;none&gt;" : StringEscapeUtils.escapeHtml(convertToMlText((Map)values.getFirst()).getDefaultValue()));
writer.write("</td><td>");
writer.write(values.getSecond() == null ? "&lt;none&gt;" : escapeHtml4(convertToMlText((Map) values.getSecond()).getDefaultValue()));
writer.write(values.getSecond() == null ? "&lt;none&gt;" : StringEscapeUtils.escapeHtml(convertToMlText((Map)values.getSecond()).getDefaultValue()));
}
else
{
Serializable oldValue = values.getFirst();
writer.write(oldValue == null ? "&lt;none&gt;" : escapeHtml4(oldValue.toString()));
writer.write(oldValue == null ? "&lt;none&gt;" : StringEscapeUtils.escapeHtml(oldValue.toString()));
writer.write("</td><td>");
Serializable newValue = values.getSecond();
writer.write(newValue == null ? "&lt;none&gt;" : escapeHtml4(newValue.toString()));
writer.write(newValue == null ? "&lt;none&gt;" : StringEscapeUtils.escapeHtml(newValue.toString()));
}
writer.write("</td></tr>");
@@ -1342,6 +1521,12 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
setNodeName(entry, json);
// TODO: Find another way for checking the event
if (entry.getEvent().equals("Delete RM Object"))
{
json.put("deleteObject", true);
}
json.put("nodeType", entry.getNodeType() == null ? "": entry.getNodeType());
json.put("event", entry.getEvent() == null ? "": getAuditEventLabel(entry.getEvent()));
json.put("identifier", entry.getIdentifier() == null ? "": entry.getIdentifier());
@@ -1421,33 +1606,23 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
case "Delete Person":
nodeName = getNodeName(entry.getBeforeProperties(), PROP_USERNAME);
json.put("noAvailableLink", true);
json.put("deletePerson", true);
break;
case "Create User Group":
nodeName = getNodeName(entry.getAfterProperties(), PROP_AUTHORITY_DISPLAY_NAME, PROP_AUTHORITY_NAME);
json.put("noAvailableLink", true);
break;
case "Delete User Group":
nodeName = getNodeName(entry.getBeforeProperties(), PROP_AUTHORITY_DISPLAY_NAME, PROP_AUTHORITY_NAME);
json.put("noAvailableLink", true);
break;
case "Add To User Group":
nodeName = getNodeName(entry.getAfterProperties(), PARENT_GROUP);
json.put("noAvailableLink", true);
break;
case "Remove From User Group":
nodeName = getNodeName(entry.getBeforeProperties(), PARENT_GROUP);
json.put("noAvailableLink", true);
break;
case "Delete RM Object":
case "Delete Hold":
nodeName = entry.getNodeName();
json.put("noAvailableLink", true);
break;
default:
@@ -1716,270 +1891,4 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
{
auditEvent(nodeRef, action.getName());
}
private class AuditTrailQueryCallback implements AuditQueryCallback
{
private final List<RecordsManagementAuditEntry> results;
private final Writer writer;
private final ReportFormat reportFormat;
private boolean firstEntry;
public AuditTrailQueryCallback(List<RecordsManagementAuditEntry> results, Writer writer, ReportFormat reportFormat)
{
this.results = results;
this.writer = writer;
this.reportFormat = reportFormat;
firstEntry = true;
}
@Override
public boolean valuesRequired()
{
return true;
}
/**
* Just log the error, but continue
*/
@Override
public boolean handleAuditEntryError(Long entryId, String errorMsg, Throwable error)
{
logger.warn(errorMsg, error);
return true;
}
@Override
@SuppressWarnings("unchecked")
public boolean handleAuditEntry(
Long entryId,
String applicationName,
String user,
long time,
Map<String, Serializable> values)
{
// Check for context shutdown
if (shutdown)
{
return false;
}
Date timestamp = new Date(time);
String eventName = null;
String fullName = null;
String userRoles = null;
NodeRef nodeRef = null;
String nodeName = null;
String nodeType = null;
String nodeIdentifier = null;
String namePath = null;
Map<QName, Serializable> beforeProperties = null;
Map<QName, Serializable> afterProperties = null;
if (values.containsKey(RM_AUDIT_DATA_EVENT_NAME))
{
// This data is /RM/event/...
eventName = (String) values.get(RM_AUDIT_DATA_EVENT_NAME);
fullName = (String) values.get(RM_AUDIT_DATA_PERSON_FULLNAME);
userRoles = (String) values.get(RM_AUDIT_DATA_PERSON_ROLES);
nodeRef = (NodeRef) values.get(RM_AUDIT_DATA_NODE_NODEREF);
nodeName = (String) values.get(RM_AUDIT_DATA_NODE_NAME);
QName nodeTypeQname = (QName) values.get(RM_AUDIT_DATA_NODE_TYPE);
nodeIdentifier = (String) values.get(RM_AUDIT_DATA_NODE_IDENTIFIER);
namePath = (String) values.get(RM_AUDIT_DATA_NODE_NAMEPATH);
beforeProperties = (Map<QName, Serializable>) values.get(RM_AUDIT_DATA_NODE_CHANGES_BEFORE);
afterProperties = (Map<QName, Serializable>) values.get(RM_AUDIT_DATA_NODE_CHANGES_AFTER);
// Convert some of the values to recognizable forms
if (nodeTypeQname != null)
{
TypeDefinition typeDef = dictionaryService.getType(nodeTypeQname);
nodeType = (typeDef != null) ? typeDef.getTitle(dictionaryService) : null;
}
}
else if (values.containsKey(DOD5015_AUDIT_DATA_EVENT_NAME))
{
// This data is /DOD5015/event/...
eventName = (String) values.get(DOD5015_AUDIT_DATA_EVENT_NAME);
fullName = (String) values.get(DOD5015_AUDIT_DATA_PERSON_FULLNAME);
userRoles = (String) values.get(DOD5015_AUDIT_DATA_PERSON_ROLES);
nodeRef = (NodeRef) values.get(DOD5015_AUDIT_DATA_NODE_NODEREF);
nodeName = (String) values.get(DOD5015_AUDIT_DATA_NODE_NAME);
QName nodeTypeQname = (QName) values.get(DOD5015_AUDIT_DATA_NODE_TYPE);
nodeIdentifier = (String) values.get(DOD5015_AUDIT_DATA_NODE_IDENTIFIER);
namePath = (String) values.get(DOD5015_AUDIT_DATA_NODE_NAMEPATH);
beforeProperties = (Map<QName, Serializable>) values.get( DOD5015_AUDIT_DATA_NODE_CHANGES_BEFORE);
afterProperties = (Map<QName, Serializable>) values.get(DOD5015_AUDIT_DATA_NODE_CHANGES_AFTER);
// Convert some of the values to recognizable forms
if (nodeTypeQname != null)
{
TypeDefinition typeDef = dictionaryService.getType(nodeTypeQname);
nodeType = (typeDef != null) ? typeDef.getTitle(dictionaryService) : null;
}
}
else if (values.containsKey(RM_AUDIT_DATA_LOGIN_USERNAME))
{
user = (String) values.get(RM_AUDIT_DATA_LOGIN_USERNAME);
if (values.containsKey(RM_AUDIT_DATA_LOGIN_ERROR))
{
eventName = RM_AUDIT_EVENT_LOGIN_FAILURE;
// The user didn't log in
fullName = user;
}
else
{
eventName = RM_AUDIT_EVENT_LOGIN_SUCCESS;
fullName = (String) values.get(RM_AUDIT_DATA_LOGIN_FULLNAME);
}
}
else if (values.containsKey(DOD5015_AUDIT_DATA_LOGIN_USERNAME))
{
user = (String) values.get(DOD5015_AUDIT_DATA_LOGIN_USERNAME);
if (values.containsKey(DOD5015_AUDIT_DATA_LOGIN_ERROR))
{
eventName = RM_AUDIT_EVENT_LOGIN_FAILURE;
// The user didn't log in
fullName = user;
}
else
{
eventName = RM_AUDIT_EVENT_LOGIN_SUCCESS;
fullName = (String) values.get(DOD5015_AUDIT_DATA_LOGIN_FULLNAME);
}
}
else
{
// This is not recognisable data
logger.warn(
"Unable to process audit entry for RM. Unexpected data: \n" +
" Entry: " + entryId + "\n" +
" Data: " + values);
// Skip it
return true;
}
if (nodeRef != null && nodeService.exists(nodeRef))
{
if ((filePlanService.isFilePlanComponent(nodeRef) &&
!AccessStatus.ALLOWED.equals(
capabilityService.getCapabilityAccessState(nodeRef, ACCESS_AUDIT_CAPABILITY))) ||
(!AccessStatus.ALLOWED.equals(permissionService.hasPermission(nodeRef, PermissionService.READ))))
{
return true;
}
checkPermissionIfHoldInProperties(beforeProperties);
checkPermissionIfHoldInProperties(afterProperties);
}
// remove any hold node refs from view
removeHoldNodeRefIfPresent(beforeProperties);
removeHoldNodeRefIfPresent(afterProperties);
// TODO: Refactor this to use the builder pattern
RecordsManagementAuditEntry entry = new RecordsManagementAuditEntry(
timestamp,
user,
fullName,
// A concatenated string of roles
userRoles,
nodeRef,
nodeName,
nodeType,
eventName,
nodeIdentifier,
namePath,
beforeProperties,
afterProperties);
// write out the entry to the file in requested format
writeEntryToFile(entry);
if (results != null)
{
results.add(entry);
}
if (logger.isDebugEnabled())
{
logger.debug(" " + entry);
}
// Keep going
return true;
}
/**
* Helper method to check permission on the hold, if any, from the given event properties
* @param eventProperties event properties
*/
private void checkPermissionIfHoldInProperties(Map<QName, Serializable> eventProperties)
{
NodeRef holdNodeRef = eventProperties != null ? (NodeRef) eventProperties.get(PROPERTY_HOLD_NODEREF) : null;
if (holdNodeRef != null)
{
if (!AccessStatus.ALLOWED.equals(
permissionService.hasPermission(holdNodeRef, PermissionService.READ)))
{
eventProperties.replace(PROPERTY_HOLD_NAME, I18NUtil.getMessage(HOLD_PERMISSION_DENIED_MSG));
}
}
}
/**
* Helper method to remove the hold node ref, if any, from the given event properties
* @param eventProperties event properties
*/
private void removeHoldNodeRefIfPresent(Map<QName, Serializable> eventProperties)
{
if (eventProperties != null)
{
eventProperties.remove(PROPERTY_HOLD_NODEREF);
}
}
/**
* Helper method to write the audit entry to file
* @param entry audit entry
*/
private void writeEntryToFile(RecordsManagementAuditEntry entry)
{
if (writer == null)
{
return;
}
try
{
if (!firstEntry)
{
if (reportFormat == ReportFormat.HTML)
{
writer.write("\n");
}
else
{
writer.write(",");
}
}
else
{
firstEntry = false;
}
// write the entry to the file
if (reportFormat == ReportFormat.JSON)
{
writer.write("\n\t\t");
}
writeAuditTrailEntry(writer, entry, reportFormat);
}
catch (IOException ioe)
{
throw new AlfrescoRuntimeException(MSG_TRAIL_FILE_FAIL, ioe);
}
}
}
}

View File

@@ -1,85 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2020 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.audit.event;
import static org.alfresco.repo.policy.Behaviour.NotificationFrequency.EVERY_EVENT;
import java.io.Serializable;
import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.hold.HoldServicePolicies;
import org.alfresco.repo.policy.annotation.Behaviour;
import org.alfresco.repo.policy.annotation.BehaviourBean;
import org.alfresco.repo.policy.annotation.BehaviourKind;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
/**
* Add to hold audit event.
*
* @author Sara Aspery
* @since 3.3
*/
@BehaviourBean
public class AddToHoldAuditEvent extends AuditEvent implements HoldServicePolicies.OnAddToHoldPolicy
{
/**
* Node Service
*/
private NodeService nodeService;
/**
* Sets the node service
*
* @param nodeService nodeService to set
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.hold.HoldServicePolicies.OnAddToHoldPolicy#onAddToHold(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
@Behaviour
(
kind = BehaviourKind.CLASS,
type = "rma:hold",
notificationFrequency = EVERY_EVENT
)
public void onAddToHold(NodeRef holdNodeRef, NodeRef contentNodeRef)
{
Map<QName, Serializable> auditProperties = HoldUtils.makePropertiesMap(holdNodeRef, nodeService);
auditProperties.put(ContentModel.PROP_NAME, nodeService.getProperty(contentNodeRef, ContentModel.PROP_NAME));
recordsManagementAuditService.auditEvent(contentNodeRef, getName(), null, auditProperties, true, false);
}
}

Some files were not shown because too many files have changed in this diff Show More