Compare commits

..

286 Commits

Author SHA1 Message Date
alfresco-build
8546c0ab2a [maven-release-plugin] prepare release V3.3.0.1 2020-02-04 13:19:05 +00:00
Ramona Popa
66cf80d2b7 Merge branch 'feature-3.3/merge_RM-7053_to_3.3.0' into 'release/V3.3.0.x'
Merge branch 'feature-3.3/RM-7053_FixCmisQueryTest' into 'release/V3.3'

See merge request records-management/records-management!1374
2020-02-03 11:51:17 +00:00
Ramona Popa
c0657e8933 Merge branch 'feature-3.3/RM-7053_FixCmisQueryTest' into 'release/V3.3'
RM-7053_FixCmisQueryTest

See merge request records-management/records-management!1365
2020-02-03 11:51:17 +00:00
Ramona Popa
bb99613b8a Merge branch 'hotfix-3.3/RM-7110_UpgradeTo3.3Fails' into 'release/V3.3.0.x'
RM-7110: Patch rm.holdAuditValuesUpdatedPatch fails to be executed when doing...

See merge request records-management/records-management!1370
2020-01-31 14:24:07 +00:00
Ramona Popa
d73bd36674 RM-7110: Patch rm.holdAuditValuesUpdatedPatch fails to be executed when doing upgrade from 3.1 to 3.3
- check if property exists before trying to update it
2020-01-31 14:24:07 +00:00
Ramona Popa
7ce514359e Merge branch 'hotfix-3.3/RM-7111_AGS_3.3_with_ACS_6.1' into 'release/V3.3.0.x'
RM-7111: AGS 3.3 can't be installed on ACS 6.1

See merge request records-management/records-management!1371
2020-01-31 14:02:36 +00:00
Ramona Popa
fc4ecc13d2 RM-7111: AGS 3.3 can't be installed on ACS 6.1
- added alfresco.min.version to 6.1
2020-01-31 14:02:36 +00:00
Claudia Agache
2ebc64e577 Update version to 3.3.0.1-SNAPSHOT 2020-01-14 12:39:07 +02:00
alfresco-build
0353691b4e [maven-release-plugin] prepare release V3.3.0 2020-01-13 15:45:26 +00:00
Christopher Shields
34fb6224d9 Merge branch 'feature/RM-7101_DeleteHold_Upgrade_Patch' into 'master'
RM-7101: [Upgrade] Delete hold audit events are not properly migrated

Closes RM-7101

See merge request records-management/records-management!1348
2020-01-13 00:00:35 +00:00
Christopher Shields
d9c3d3c219 RM-7101: [Upgrade] Delete hold audit events are not properly migrated 2020-01-13 00:00:34 +00:00
Christopher Shields
b0032f69b2 Merge branch 'feature/RM-7098_AddRemoveFromHolds_Upgrade_Patch' into 'master'
RM-7098: [Upgrade] Add to Hold and Remove from hold audit events are not properly migrated

Closes RM-7098

See merge request records-management/records-management!1345
2020-01-10 09:23:06 +00:00
Ramona Popa
8027c10b4b RM-7098: [Upgrade] Add to Hold and Remove from hold audit events are not properly migrated 2020-01-10 09:23:06 +00:00
gbroadbent
41e06633b5 RUSSIAN: Updated files for AGS 3.3 based on EN version of 2020-01-03_master branch. Full fix for https://issues.alfresco.com/jira/browse/LOC-185 2020-01-09 11:01:56 +00:00
gbroadbent
3995c8ef99 SIMPLIFIED CHINESE: Updated files for AGS 3.3 based on EN version of 2020-01-03_master branch. Partial fix for https://issues.alfresco.com/jira/browse/LOC-185 2020-01-09 10:21:57 +00:00
gbroadbent
d0aae1fd32 BRAZILIAN PORTUGUESE: Updated files for AGS 3.3 based on EN version of 2020-01-03_master branch. Partial fix for https://issues.alfresco.com/jira/browse/LOC-185 2020-01-09 10:20:39 +00:00
gbroadbent
7f66c4a90f DUTCH: Updated files for AGS 3.3 based on EN version of 2020-01-03_master branch. Partial fix for https://issues.alfresco.com/jira/browse/LOC-185 2020-01-09 10:20:05 +00:00
gbroadbent
c316c43157 NORWEGIAN Bokmal: Updated files for AGS 3.3 based on EN version of 2020-01-03_master branch. Partial fix for https://issues.alfresco.com/jira/browse/LOC-185 2020-01-09 10:19:30 +00:00
gbroadbent
cd2ff6e461 JAPANESE: Updated files for AGS 3.3 based on EN version of 2020-01-03_master branch. Partial fix for https://issues.alfresco.com/jira/browse/LOC-185 2020-01-09 10:19:01 +00:00
gbroadbent
31776aa101 ITALIAN: Updated files for AGS 3.3 based on EN version of 2020-01-03_master branch. Partial fix for https://issues.alfresco.com/jira/browse/LOC-185 2020-01-09 10:18:32 +00:00
gbroadbent
386fdb88d4 FRENCH: Updated files for AGS 3.3 based on EN version of 2020-01-03_master branch. Partial fix for https://issues.alfresco.com/jira/browse/LOC-185 2020-01-09 10:18:02 +00:00
gbroadbent
bdb2f80e74 SPANISH: Updated files for AGS 3.3 based on EN version of 2020-01-03_master branch. Partial fix for https://issues.alfresco.com/jira/browse/LOC-185 2020-01-09 10:17:37 +00:00
gbroadbent
7f74862eaa GERMAN: Updated files for AGS 3.3 based on EN version of 2020-01-03_master branch. Partial fix for https://issues.alfresco.com/jira/browse/LOC-185 2020-01-09 10:16:58 +00:00
Sara Aspery
d9e1c21cd6 Update license headers 2020-01-03 10:53:19 +00:00
Sara Aspery
187db478a5 Merge branch 'release/V3.2' 2020-01-03 10:45:13 +00:00
Sara Aspery
e1da6ab294 Update license headers 2020-01-02 20:19:58 +00:00
Sara Aspery
18b14ceca8 Merge branch 'release/V3.1' into release/V3.2 2020-01-02 20:15:28 +00:00
Sara Aspery
bd67c3bf6b Update license headers 2020-01-02 18:27:23 +00:00
Sara Aspery
f7e69629bb Merge branch 'release/V3.0' into release/V3.1 2020-01-02 18:21:48 +00:00
Sara Aspery
03eee1b8e3 Update license headers 2020-01-02 16:20:24 +00:00
Sara Aspery
841340c1e8 Merge branch 'release/V2.7' into release/V3.0
# Conflicts:
#	rm-automation/rm-automation-ui/src/test/java/org/alfresco/test/enterprise/security/apiTesting/SearchClassifiedContent.java
#	rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/job/AutomaticDispositionTest.java
#	rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RMCaveatConfigServiceImplTest.java
#	rm-enterprise/rm-enterprise-repo/src/main/java/org/alfresco/module/org_alfresco_module_rm/util/SecurityMarkChecker.java
#	rm-enterprise/rm-enterprise-repo/src/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/classification/interceptor/DocumentSearchClassificationEnforcementTest.java
#	rm-enterprise/rm-enterprise-repo/src/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/classification/interceptor/RecordSearchClassificationEnforcementTest.java
#	rm-enterprise/rm-enterprise-repo/src/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/classification/interceptor/SavedSearchClassificationEnforcementTest.java
#	rm-enterprise/rm-enterprise-repo/src/unit-test/java/org/alfresco/module/org_alfresco_module_rm/util/SecurityMarkCheckerUnitTest.java
2020-01-02 16:15:49 +00:00
Sara Aspery
b48d31457a Update license headers 2020-01-02 15:05:02 +00:00
Sara Aspery
0ed125b0b5 Merge branch 'release/V2.6' into release/V2.7
# Conflicts:
#	rm-enterprise/rm-enterprise-repo/src/main/java/org/alfresco/module/org_alfresco_module_rm/model/AbstractSecureItem.java
2020-01-02 14:19:01 +00:00
Sara Aspery
943dc45a10 Update license headers 2020-01-02 13:57:59 +00:00
Sara Aspery
3819044347 Merge branch 'feature/RM-7062_NoReadOnHoldCanSeeAuditEvent' into 'master'
RM-7062 Check hold permission for view audit event

Closes RM-7062

See merge request records-management/records-management!1324
2019-12-20 19:10:12 +00:00
Claudia Agache
4d19133ede Merge branch 'feature/RM-7081_ReduceAutomationProjSonarIssues' into 'master'
RM-7081 Reduce automation proj sonar issues

Closes RM-7081

See merge request records-management/records-management!1337
2019-12-20 14:49:19 +00:00
cagache
8057ed6033 Remove mvn clean 2019-12-20 14:38:44 +02:00
cagache
68554bba93 Revert "Added install_first source clear scan directive"
This reverts commit 3a81f88f
2019-12-20 14:37:51 +02:00
cagache
8e916705d4 Revert "Added back fail-fast"
This reverts commit b6765cd5
2019-12-20 14:37:32 +02:00
cagache
b6765cd59b Added back fail-fast 2019-12-20 14:25:20 +02:00
cagache
3a81f88fcd Added install_first source clear scan directive 2019-12-20 11:40:49 +02:00
cagache
92b2f04504 Merge remote-tracking branch 'remotes/origin/master' into feature/RM-7081_ReduceAutomationProjSonarIssues 2019-12-20 10:38:08 +02:00
cagache
e9697349c9 Upgrade jackson-databind from 2.9.10 to 2.9.10.1 2019-12-20 09:50:58 +02:00
Sara Aspery
ff5f8f8d68 RM-7062 fix for failing tests 2019-12-20 02:20:13 +00:00
Sara Aspery
46918e41eb RM-7062 add noderef to audit entry for hold 2019-12-19 22:46:07 +00:00
Roxana Lucanu
8cdd220526 Merge branch 'feature/RM_7096_VeracodeScanExcludeAutomation_no' into 'master'
RM-7096 Source clear scan exclude automation project

See merge request records-management/records-management!1338
2019-12-19 15:14:39 +00:00
cagache
504c27f5aa Added comment 2019-12-19 17:00:42 +02:00
cagache
9be7a77a70 Don't fail fast 2019-12-19 16:20:37 +02:00
cagache
0ea5725249 Exclude benchmark project from source clear scan using a custom maven command 2019-12-19 15:19:12 +02:00
cagache
98f91c52ad Try to exclude automation project from source clear scan using a custom maven command 2019-12-19 13:56:53 +02:00
cagache
3e5dcb40fc Try to exclude automation project from sourceclear scan using a custom maven command 2019-12-19 12:46:16 +02:00
cagache
f044836b69 Try to exclude automation project from sourceclear scan using a custom maven command 2019-12-19 12:08:20 +02:00
cagache
a7fb91fa5c Try to exclude automation project from sourceclear scan using a custom maven command 2019-12-19 11:20:26 +02:00
cagache
df1ded7eee Try to exclude automation project from sourceclear scan using a custom maven command 2019-12-19 10:42:34 +02:00
cagache
7d99065661 Exclude automation project from sourceclear scan 2019-12-19 10:25:52 +02:00
cagache
2ba2fb77ee Exclude automation project from sourceclear scan 2019-12-19 10:20:49 +02:00
cagache
a3e27059de Exclude automation project from sourceclear scan 2019-12-19 09:42:50 +02:00
Sara Aspery
5b68c47866 RM-7062 fix integration tests 2019-12-17 08:37:15 +00:00
cagache
e2e44eb9c7 Reduce Sonar issues from automation-community-rest-api 2019-12-16 15:14:31 +02:00
Sara Aspery
f1b7fe5b2c Merge branch 'master' into feature/RM-7062_NoReadOnHoldCanSeeAuditEvent 2019-12-15 08:46:11 +00:00
Sara Aspery
f2d1e11497 RM-7062 Fix automation tests 2019-12-15 07:18:33 +00:00
Sara Aspery
bf0153f02b RM-7062 Updates from review 2019-12-15 07:17:59 +00:00
Claudia Agache
d5fbdac23c Merge branch 'feature/RM-7093_UpdateItemLocation' into 'master'
RM-7093 Update item location to include the provenience site

Closes RM-7093

See merge request records-management/records-management!1335
2019-12-13 09:32:14 +00:00
Sara Aspery
842f586d1f RM-7062 Unit tests 2019-12-13 07:21:35 +00:00
Claudia Agache
d1167e86c4 Merge branch 'feature/RM-7060_TestsForRecordSearchAspect_no' into 'master'
RM-7060 Tests for recordsearch aspect

Closes RM-7060

See merge request records-management/records-management!1334
2019-12-13 07:11:23 +00:00
cagache
efb2c2156e review comments 2019-12-12 12:06:49 +02:00
cagache
f5b14a8301 Merge remote-tracking branch 'remotes/origin/master' into feature/RM-7060_TestsForRecordSearchAspect_no 2019-12-12 11:41:25 +02:00
Claudia Agache
8a7f584679 Merge branch 'merge/RM-7060_FixSearchAspect' into 'master'
Resolve RM-7060 "Merge/ fixsearchaspect"

Closes RM-7060 and RM-7051

See merge request records-management/records-management!1333
2019-12-12 09:35:20 +00:00
cagache
41e41902c0 RM-7093 Update item location to include the provenience site 2019-12-11 16:16:49 +02:00
Roxana Lucanu
50df5ac0a2 Merge remote-tracking branch 'origin/master' into merge/RM-7060_FixSearchAspect 2019-12-10 16:09:03 +02:00
Ross Gale
d3ac41f364 Merge branch 'merge/RM-7051_disposition' into 'master'
Resolve RM-7051 "Merge/ disposition"

Closes RM-7051

See merge request records-management/records-management!1328
2019-12-10 13:22:21 +00:00
Roxana Lucanu
91d80e006c Merge branch 'release/V3.2' into merge/RM-7060_FixSearchAspect 2019-12-10 14:33:19 +02:00
Roxana Lucanu
e803b01388 Merge branch 'merge-3.2/RM-7060_FixSearchAspect' into 'release/V3.2'
Resolve RM-7060 "Merge 3.2/ fixsearchaspect"

See merge request records-management/records-management!1332
2019-12-10 12:17:15 +00:00
Ross Gale
149314d068 RM-7051 replacing string utils ref 2019-12-10 10:41:12 +00:00
cagache
69d8fc8be2 Check rma:recordSearch aspect is still present after record move 2019-12-10 10:58:10 +02:00
Roxana Lucanu
91261ef300 Merge branch 'release/V3.1' into merge-3.2/RM-7060_FixSearchAspect 2019-12-10 09:09:56 +02:00
Roxana Lucanu
04a74aa699 Merge branch 'merge-3.1/RM-7060_FixSearchAspect' into 'release/V3.1'
Resolve RM-7060 "Merge 3.1/ fixsearchaspect"

See merge request records-management/records-management!1331
2019-12-10 07:04:45 +00:00
cagache
fcc10dd091 Check rma:recordSearch aspect is still present after records filing 2019-12-09 16:57:31 +02:00
Roxana Lucanu
d0cb729f35 Merge branch 'release/V3.0' into merge-3.1/RM-7060_FixSearchAspect 2019-12-09 14:39:06 +02:00
Roxana Lucanu
9ef79baddd Merge branch 'merge-3.0/RM-7060_FixSearchAspect' into 'release/V3.0'
Resolve RM-7060 "Merge 3.0/ fixsearchaspect"

See merge request records-management/records-management!1330
2019-12-09 12:36:21 +00:00
Roxana Lucanu
45e39aa4bd Merge branch 'release/V2.7' into merge-3.0/RM-7060_FixSearchAspect 2019-12-09 10:49:30 +02:00
Roxana Lucanu
04d89e16b5 Merge branch 'release/V2.7' into merge-3.0/RM-7060_FixSearchAspect 2019-12-09 10:44:26 +02:00
Roxana Lucanu
8f9faf6b0e Merge branch 'merge-2.7/RM-7060_FixSearchAspect' into 'release/V2.7'
Resolve RM-7060 "Merge 2.7/ fixsearchaspect"

See merge request records-management/records-management!1329
2019-12-09 08:24:51 +00:00
Ross Gale
7af0b3f7f6 Merge remote-tracking branch 'origin/release/V3.2' into merge/RM-7051 2019-12-05 15:35:01 +00:00
Ramona Popa
56b82d8380 Merge branch 'feature/RM-7092_BrokenLinkForUserGroupEvents' into 'master'
RM-7092: Broken link for Add to / Remove from user group events

Closes RM-7092

See merge request records-management/records-management!1327
2019-12-05 13:07:21 +00:00
Ramona Popa
fa8104cdc2 RM-7092: Broken link for Add to / Remove from user group events
- removed link in audit list for user groups events
2019-12-05 13:07:21 +00:00
Ross Gale
ebf8a906a1 Merge branch 'merge-3.2/RM-7051_DispositionWebScript' into 'release/V3.2'
Resolve RM-7051 "Merge 3.2/ dispositionwebscript"

See merge request records-management/records-management!1323
2019-12-05 12:42:59 +00:00
Rodica Sutu
ace2728b16 Merge branch 'feature/RM-7066_UpdateToACS62' into 'master'
Resolve RM-7066 "Feature/ updatetoacs62"

Closes RM-7066

See merge request records-management/records-management!1314
2019-12-05 08:33:56 +00:00
Ramona Popa
1672dd00d4 Merge branch 'feature/RM-7069_InconsistencyInDisplayingLocationAndTimestamp' into 'master'
RM-7069: Display of the location is not consistent in all audit reports

Closes RM-7069

See merge request records-management/records-management!1322
2019-12-05 07:34:25 +00:00
Ramona Popa
8a67a6286d RM-7069: Display of the location is not consistent in all audit reports
- made display of location and timestamp consistent
2019-12-05 07:34:25 +00:00
Sara Aspery
050ab580ee RM-7062 Check hold permission for view audit event 2019-12-05 05:11:53 +00:00
Ross Gale
3809249576 RM-7051 updating code to deal with held content after 3.2 change 2019-12-04 14:01:54 +00:00
Roxana Lucanu
6035370684 Merge branch 'release/V2.6' into merge-2.7/RM-7060_FixSearchAspect 2019-12-04 15:44:29 +02:00
Roxana Lucanu
ac12711512 Merge branch 'merge-2.6/RM-7060_FixSearchAspect' into 'release/V2.6'
Resolve RM-7060 "Merge 2.6/ fixsearchaspect"

See merge request records-management/records-management!1321
2019-12-04 13:40:22 +00:00
Sara Aspery
4bf23c1d6a Merge branch 'feature/RM-7064_FixPermissionsForDeleteHoldsNodeAPI' into 'master'
RM-7064 check permissions for delete node

Closes RM-7064

See merge request records-management/records-management!1316
2019-12-03 15:15:47 +00:00
Roxana Lucanu
8d5ff56f8f Merge branch 'release/V2.5' into merge-2.6/RM-7060_FixSearchAspect 2019-12-03 11:58:42 +02:00
Sara Aspery
4b4323dd58 RM-7064 Fix unit tests after review updates 2019-12-03 06:15:03 +00:00
Rodica Sutu
2629b65eb1 changes to address code review comments 2019-12-02 15:52:31 +02:00
Rodica Sutu
3885c4462c remove the content property as ContentPropertyRestrictionInterceptor will not allow update of content via nodeService.addProperties 2019-12-02 10:50:35 +02:00
Ross Gale
94cb6346ce Merge remote-tracking branch 'origin/release/V3.1' into merge-3.2/mergeUp 2019-12-02 08:08:06 +00:00
Ross Gale
77799d1632 Merge branch 'merge-3.1/mergeUp' into 'release/V3.1'
Merge 3.1/merge up

See merge request records-management/records-management!1320
2019-12-02 07:58:27 +00:00
Ross Gale
6b01d76ed1 Merge branch 'release/V3.0' into merge-3.1/mergeUp 2019-11-29 15:55:07 +00:00
Ross Gale
d74cbe52b6 Merge branch 'merge-3.0/mergeUp' into 'release/V3.0'
Merge 3.0/merge up

See merge request records-management/records-management!1319
2019-11-29 15:52:19 +00:00
Rodica Sutu
9d17f70cd3 Merge branch 'master' of https://git.alfresco.com/records-management/records-management into feature/RM-7066_UpdateToACS62 2019-11-29 14:55:08 +02:00
Ross Gale
7048f30e89 Record only merge of version change. 2019-11-29 12:12:07 +00:00
Ross Gale
3505e8dfd6 fix conflicts 2019-11-29 10:59:47 +00:00
Sara Aspery
fb6ca169a0 Merge branch 'feature/RM-7070_ShowRoleForActiveContentInAudit' into 'master'
RM-7070 Show role in audit for active content

Closes RM-7070

See merge request records-management/records-management!1317
2019-11-29 02:50:59 +00:00
Sara Aspery
976748ee0f RM-7068 updates from review 2019-11-28 17:07:20 +00:00
Sara Aspery
b9d923d0d0 RM-7070 updates from review 2019-11-28 16:48:21 +00:00
Rodica Sutu
044c571df5 Merge branch 'master' of https://git.alfresco.com/records-management/records-management into feature/RM-7066_UpdateToACS62 2019-11-28 16:33:07 +02:00
Rodica Sutu
843782712e fix testFillingPermissionOnSourceAndTarget 2019-11-28 16:15:52 +02:00
Roxana Lucanu
89cc90cef7 Merge branch 'feature-2.5/RM-7060_FixSearchAspect' into 'release/V2.5'
RM-7060 Reapply search aspect when filing/moving

See merge request records-management/records-management!1315
2019-11-28 13:22:55 +00:00
Ramona Popa
6249537356 Merge branch 'feature/RM-7063_UserWithNoReadCanSeeAudit' into 'master'
RM-7063: User with no Read on active content can see Add To Hold/Remove From Hold audit entries

Closes RM-7063

See merge request records-management/records-management!1312
2019-11-28 11:04:15 +00:00
Ramona Popa
26ed36d312 RM-7063: User with no Read on active content can see Add To Hold/Remove From Hold audit entries
- filter entries based on READ permissions too
2019-11-28 11:04:15 +00:00
Sara Aspery
81ab6da25d Merge branch 'feature/RM-7068_ShortenErrorMsgForDeleteHold' into 'master'
Resolve RM-7068 "Feature/ shorten error msg for delete hold"

Closes RM-7068

See merge request records-management/records-management!1313
2019-11-28 06:55:02 +00:00
Sara Aspery
3c1df3c25a RM-7070 Show role in audit for active content 2019-11-28 03:54:07 +00:00
Sara Aspery
a0868776d5 RM-7068 updates from review 2019-11-28 01:45:40 +00:00
Sara Aspery
fe502aadec RM-7064 check permissions for delete node 2019-11-28 01:09:21 +00:00
Rodica Sutu
27a6a433c9 changes for ACS 6.2.0.ga 2019-11-27 15:23:28 +02:00
Roxana Lucanu
f138d31436 RM-7060 Fix integration tests 2019-11-27 11:28:32 +02:00
Sara Aspery
3c95f9c4f8 RM-7068 remove unused import statement 2019-11-27 05:58:00 +00:00
Sara Aspery
e8f67c8b75 RM-7068 restrict items in delete hold error msg 2019-11-27 05:55:29 +00:00
Roxana Lucanu
a7f2dec355 RM-7060 Reapply search aspect when filing/moving 2019-11-26 21:57:35 +02:00
Rodica Sutu
78d2570d3d update min version ACS version for the text context 2019-11-26 16:05:47 +02:00
Ross Gale
3c2a6f269c Merge branch 'merge-2.7/RM-7051_RecordOnly' into 'release/V2.7'
Resolve RM-7051 "Merge 2.7/ recordonly"

See merge request records-management/records-management!1311
2019-11-26 13:24:29 +00:00
Ross Gale
850dd8fc15 Record only merge of version change. 2019-11-26 11:36:53 +00:00
Ross Gale
78bec90215 Merge branch 'merge-2.6/RM-7051_RecordOnly' into 'release/V2.6'
Resolve RM-7051 "Merge 2.6/ recordonly"

See merge request records-management/records-management!1310
2019-11-26 11:28:38 +00:00
Ross Gale
cb5e060731 Record only merge of version change. 2019-11-26 11:22:35 +00:00
Ross Gale
c9f73f70bc Merge branch 'merge-2.5/RM-7051_RecordOnly' into 'release/V2.5'
Resolve RM-7051 "Merge 2.5/ recordonly"

See merge request records-management/records-management!1309
2019-11-26 11:16:17 +00:00
Ross Gale
8c721c710c Record only merge of version change. 2019-11-26 10:38:34 +00:00
Ross Gale
9d3dae0666 Merge branch 'merge-2.7/RM-7051_MergeUp' into 'release/V2.7'
Resolve RM-7051 "Merge 2.7/ mergeup"

See merge request records-management/records-management!1308
2019-11-26 08:43:17 +00:00
Rodica Sutu
6a7e346e22 replace the ARGs parameter from Dockerfile 2019-11-26 10:18:29 +02:00
Rodica Sutu
c7e920053e update the docker dependencies on community to ACS 6.2.0.ea 2019-11-26 09:27:49 +02:00
Rodica Sutu
5ccea06272 replace the org.apache.commons.lang references to org.apache.commons.lang3 2019-11-26 09:11:08 +02:00
Claudia Agache
486cffb939 Merge branch 'feature/RM-7050_LinkToHeldItemUITests' into 'master'
RM-7050 Link to Held items UI Tests

Closes RM-7050

See merge request records-management/records-management!1302
2019-11-26 07:01:34 +00:00
Ramona Popa
4d08521b41 Merge branch 'feature/RM-7047_LinkToHeldItem' into 'master'
RM-7047: Link to held item from audit entry

Closes RM-7047

See merge request records-management/records-management!1300
2019-11-26 07:00:28 +00:00
Ramona Popa
58280bc323 RM-7047: Link to held item from audit entry
- added support for link to held items in audit
   - changed style class for existing links in audit entry
2019-11-26 07:00:28 +00:00
Rodica Sutu
54d0d7f7f8 update community dependencies to ones from ACS 6.2.0.ea 2019-11-26 08:50:32 +02:00
Ross Gale
813ed3ced6 Update version.properties 2019-11-25 08:35:50 +00:00
Ross Gale
3937379587 RM-7051 resolving conflict 2019-11-25 08:31:09 +00:00
Ross Gale
93f3458498 Merge branch 'merge-2.6/RM-7051_mergeUp' into 'release/V2.6'
Resolve RM-7051 "Merge 2.6/ mergeup"

See merge request records-management/records-management!1306
2019-11-22 18:15:24 +00:00
Ross Gale
ffaf55c7d3 Merge branch 'hotfix-2.5/RM-7051_Disposition' into 'release/V2.5.3.x'
Resolve RM-7051 "Hotfix 2.5/ disposition"

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

Adds web script to ensure all records have correct disposition instructions
2019-11-22 18:15:24 +00:00
Ross Gale
0fb8c59172 Merge branch 'merge-2.5/RM-7051_mergeUp' into 'release/V2.5'
Resolve RM-7051 "Merge 2.5/ mergeup"

See merge request records-management/records-management!1305
2019-11-22 14:25:27 +00:00
Ross Gale
df6d92d031 Merge branch 'hotfix-2.5/RM-7051_Disposition' into 'release/V2.5.3.x'
Resolve RM-7051 "Hotfix 2.5/ disposition"

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

Adds web script to ensure all records have correct disposition instructions
2019-11-22 14:25:27 +00:00
cagache
d61a01bca4 Merge remote-tracking branch 'remotes/origin/feature/RM-7047_LinkToHeldItem' into feature/RM-7050_LinkToHeldItemUITests 2019-11-22 15:55:24 +02:00
Ramona Popa
7f89f150e7 RM-7047: Link to held item from audit entry
- addressed review suggestions
2019-11-22 14:39:19 +02:00
Ramona Popa
c1a8ff0b43 Merge branch 'master' into feature/RM-7047_LinkToHeldItem
* master:
  fix test
  removed test as per RM-7061 resolution
  small fixes
  RM-6930 another review update, correct typo in existing message
  RM-6930 review updates
  RM-6930 review updates
  Code review comments (check node path for add to hold and remove from hold audit entries)
  Code review comments
  Delete hold using RM Actions API
  Changed the audited node
  replaced the todos
  Sonar: Format specifiers should be used instead of string concatenation. Sonar: Replace the type specification in this constructor call with the diamond operator ("<>")
  removed unused imports
  Refactored audit tests and holds api
  update method names
  RM-7033 Automate tests for Audit create, delete, add to, and remove from holds
  removed duplicate methods
  RM-6930 adding permissions check for active content in holds defore deletion
2019-11-22 11:27:26 +02:00
Ramona Popa
cc1a6f1971 RM-7047: Link to held item from audit entry
- changes after review
2019-11-22 11:27:08 +02:00
Ross Gale
12aa2c4616 Updating version number after release 2019-11-22 08:55:41 +00:00
cagache
639e7f33dc Merge remote-tracking branch 'remotes/origin/master' into feature/RM-7050_LinkToHeldItemUITests 2019-11-22 09:56:23 +02:00
Claudia Agache
f956f97cbb Merge branch 'feature/RM-7033_AuditHoldTests_no' into 'master'
RM-7033 Audit hold tests

See merge request records-management/records-management!1294
2019-11-22 06:17:59 +00:00
alfresco-build
eaca05e4b6 [maven-release-plugin] prepare for next development iteration 2019-11-21 18:15:33 +00:00
alfresco-build
79de26057c [maven-release-plugin] prepare release V2.5.3.3 2019-11-21 18:15:29 +00:00
Sara Aspery
150f2e1587 Merge branch 'feature/RM-6930_DeleteHold' into 'master'
RM-6930 adding permissions check for active content in holds defore deletion

Closes RM-6930

See merge request records-management/records-management!1286
2019-11-21 16:09:49 +00:00
cagache
a427eb6423 Merge remote-tracking branch 'remotes/origin/feature/RM-7047_LinkToHeldItem' into feature/RM-7050_LinkToHeldItemUITests 2019-11-21 16:32:38 +02:00
Ross Gale
e0dd0ca886 Merge branch 'hotfix-2.5/RM-7051_Disposition' into 'release/V2.5.3.x'
Resolve RM-7051 "Hotfix 2.5/ disposition"

See merge request records-management/records-management!1303
2019-11-21 14:32:24 +00:00
Ramona Popa
bc7caea25c RM-7047: Link to held item from audit entry
- consider Delete Hold as deleteObject
2019-11-21 14:11:57 +02:00
Ross Gale
8f42f0caf0 RM-7051 merge 2019-11-21 11:08:39 +00:00
Ross Gale
9e4586b699 RM-7051 review comments 2019-11-21 11:04:35 +00:00
Sara Aspery
c6302fd034 Merge branch 'master' into feature/RM-6930_DeleteHold 2019-11-21 10:07:15 +00:00
cagache
f75e6eedda Merge remote-tracking branch 'remotes/origin/master' into feature/RM-7033_AuditHoldTests_no 2019-11-21 12:04:39 +02:00
Ramona Popa
d98d5538d0 Merge branch 'master' into feature/RM-7047_LinkToHeldItem
* master:
  Code review changes
  Code review changes
2019-11-21 12:01:52 +02:00
Christopher Shields
dfaff93661 Merge branch 'feature/RM-7029_RemoveFromHold' into 'master'
Resolve RM-7029 "Feature/ removefromhold"

Closes RM-7029

See merge request records-management/records-management!1304
2019-11-21 09:52:41 +00:00
Roy Wetherall
347a2ef9db Prevent unwanted audit entries appearing when updating the records 2019-11-21 13:54:09 +11:00
Ross Gale
022647d84b RM-7051 simplyfing sql and adding check for links 2019-11-21 01:16:37 +00:00
Ross Gale
9099444e2d RM-7051 updating messaging 2019-11-20 13:33:35 +00:00
Ramona Popa
f94b580dc9 Merge branch 'master' into feature/RM-7047_LinkToHeldItem
* master:
2019-11-20 14:56:11 +02:00
Chris Shields
5d08fcf1d4 Merge branch 'master' into feature/RM-7029_RemoveFromHold 2019-11-20 11:24:17 +00:00
Chris Shields
0b3f1c793d Code review changes 2019-11-20 11:16:04 +00:00
cagache
710e738f16 fix test 2019-11-20 13:07:45 +02:00
Ross Gale
9c1904db77 RM-7051 running the find records and update as system 2019-11-20 10:51:33 +00:00
cagache
b059e96fac removed test as per RM-7061 resolution 2019-11-20 12:19:11 +02:00
Sara Aspery
6cec2bb099 Merge branch 'master' into feature/RM-6930_DeleteHold 2019-11-20 09:49:29 +00:00
cagache
4fd762ff43 small fixes 2019-11-20 11:24:21 +02:00
cagache
1b0b871fa3 Merge remote-tracking branch 'remotes/origin/feature/RM-7029_RemoveFromHold' into feature/RM-7033_AuditHoldTests_no 2019-11-20 08:38:25 +02:00
cagache
92b88491e5 Merge remote-tracking branch 'remotes/origin/master' into feature/RM-7033_AuditHoldTests_no 2019-11-20 08:37:52 +02:00
Chris Shields
bc5c5bd51d Code review changes 2019-11-19 21:11:50 +00:00
Sara Aspery
00c7f87779 Merge branch 'feature/RM-7028_Add_Add_To_Hold_ToAudit' into 'master'
RM-7028 Audit add to hold

Closes RM-7028

See merge request records-management/records-management!1296
2019-11-19 18:21:37 +00:00
Ross Gale
cdf1118b29 RM-7051 removing previous sql code 2019-11-19 16:20:39 +00:00
Ross Gale
364ee7838a RM-7051 removing patch code updating webscript 2019-11-19 13:38:40 +00:00
Chris Shields
4a89c38f2d Merge branch 'feature/RM-7028_Add_Add_To_Hold_ToAudit' into feature/RM-7029_RemoveFromHold 2019-11-19 12:14:04 +00:00
Chris Shields
ad963bb24e RM-7029 Audit remove from hold 2019-11-19 12:05:06 +00:00
Sara Aspery
8140859d03 RM-7028 review updates 2019-11-19 11:15:45 +00:00
Roy Wetherall
dca4cf154f Added web script to do record disposition schedule updates 2019-11-19 20:56:26 +11:00
Ross Gale
898a95cd85 RM-7051 updating patch code 2019-11-18 23:28:08 +00:00
Sara Aspery
30e3ea689f RM-7028 review updates 2019-11-18 15:59:54 +00:00
Sara Aspery
e9be5a4188 Merge branch 'master' into feature/RM-7028_Add_Add_To_Hold_ToAudit 2019-11-18 14:12:23 +00:00
Sara Aspery
7fbf695a32 RM-6930 another review update, correct typo in existing message 2019-11-18 14:07:55 +00:00
Ross Gale
490a212e6a RM-7051 updating messaging to report on batch completion 2019-11-18 14:05:17 +00:00
Sara Aspery
9ff5d66024 RM-6930 review updates 2019-11-18 10:56:45 +00:00
Ross Gale
bfe2e6fe83 RM-7051 adding code to deal with held records/folders 2019-11-18 10:55:39 +00:00
Sara Aspery
c8afa0db31 RM-6930 review updates 2019-11-18 10:47:09 +00:00
Ramona Popa
ae42ec33af Merge branch 'feature/RM-7057_DeleteHoldNotAuditedWithNodesApi' into 'master'
RM-7057: Delete hold event isn't audited if hold is deleted using nodes api

Closes RM-7057

See merge request records-management/records-management!1301
2019-11-18 08:34:54 +00:00
Ramona Popa
c386f1bbd8 RM-7057: Delete hold event isn't audited if hold is deleted using nodes api
-listen to beforeDeleteNode policy rather than beforeDeleteHold one to cover the delete the hold from api as well
2019-11-18 08:34:54 +00:00
Sara Aspery
b2ae5242e9 RM-6930 review updates 2019-11-18 01:25:34 +00:00
Ross Gale
5259625d04 RM-7051 adding batch code 2019-11-17 22:20:31 +00:00
Ross Gale
e603eaf0eb RM-7051 adding batch code 2019-11-17 22:07:31 +00:00
Sara Aspery
d4c9be9f11 RM-7028 integ test fix, locn refactor, multi files fix 2019-11-16 14:11:06 +00:00
cagache
804a7df593 Merge remote-tracking branch 'remotes/origin/feature/RM-7047_LinkToHeldItem' into feature/RM-7050_LinkToHeldItemUITests 2019-11-14 09:25:07 +02:00
Ross Gale
098be4c2da Initial patch code to apply disposition fix to records 2019-11-13 15:52:29 +00:00
Sara Aspery
394ae36a02 RM-7028 fix unit test 2019-11-12 12:11:34 +00:00
cagache
159e78517e Merge remote-tracking branch 'remotes/origin/master' into feature/RM-7033_AuditHoldTests_no 2019-11-12 11:17:27 +02:00
Roxana Lucanu
f94b9a9f35 Merge branch 'feature/RM-7054_HeldContentPolicyChanges' into 'master'
RM-7054 Changes on held content policies

Closes RM-7054

See merge request records-management/records-management!1297
2019-11-12 09:15:55 +00:00
cagache
d682a5253d Code review comments (check node path for add to hold and remove from hold audit entries) 2019-11-12 11:15:45 +02:00
Roxana Lucanu
1278258a74 RM-7054 code review changes 2019-11-12 10:36:42 +02:00
Sara Aspery
55e5267234 RM-7028 show location and fix multiple holds 2019-11-12 05:13:40 +00:00
cagache
4fdc23a230 Merge remote-tracking branch 'remotes/origin/feature/RM-7054_HeldContentPolicyChanges' into feature/RM-7033_AuditHoldTests_no 2019-11-11 14:27:52 +02:00
cagache
a8b0556796 Merge remote-tracking branch 'remotes/origin/feature/RM-7028_Add_Add_To_Hold_ToAudit' into feature/RM-7033_AuditHoldTests_no 2019-11-11 14:08:09 +02:00
cagache
d185718be6 Code review comments 2019-11-11 11:21:28 +02:00
cagache
4e10ca09e7 Delete hold using RM Actions API 2019-11-08 16:02:16 +02:00
Roxana Lucanu
65f30701d1 RM-7054 Changes on held content policies 2019-11-08 14:33:43 +02:00
Sara Aspery
fa625379e2 RM-7028 fix integration tests 2019-11-08 08:35:50 +00:00
cagache
41283a218b Changed the audited node 2019-11-08 10:20:16 +02:00
cagache
6b786fca21 Merge remote-tracking branch 'remotes/origin/master' into feature/RM-7033_AuditHoldTests_no 2019-11-08 10:05:49 +02:00
Sara Aspery
59253c84ae Merge branch 'feature/RM-7027_Add_Hold_Deleted_ToAudit' into 'master'
Resolve RM-7027 "Feature/ add hold deleted to audit"

Closes RM-7027

See merge request records-management/records-management!1295
2019-11-07 22:53:56 +00:00
Sara Aspery
295350bb08 RM-7028 update from review 2019-11-07 12:54:15 +00:00
cagache
581d796783 Merge remote-tracking branch 'remotes/origin/master' into feature/RM-7033_AuditHoldTests_no 2019-11-07 14:29:08 +02:00
Sara Aspery
9ad116e1c5 Merge branch 'feature/RM-7026_Add_HoldCreated_ToAudit' into 'master'
Resolve RM-7026 "Feature/ add holdcreated toaudit"

Closes RM-7026

See merge request records-management/records-management!1283
2019-11-07 12:23:21 +00:00
cagache
1c2b4da16a replaced the todos 2019-11-07 12:36:52 +02:00
cagache
659c945506 Sonar: Format specifiers should be used instead of string concatenation.
Sonar: Replace the type specification in this constructor call with the diamond operator ("<>")
2019-11-07 10:10:25 +02:00
Sara Aspery
e0d96d3219 Merge branch 'master' into feature/RM-6930_DeleteHold
# Conflicts:
#	rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImplUnitTest.java
2019-11-06 23:35:27 +00:00
Sara Aspery
606f599059 RM-7028 Audit add to hold 2019-11-06 23:20:28 +00:00
Sara Aspery
acc06e55f5 RM-7027 Audit delete hold 2019-11-06 22:39:44 +00:00
Sara Aspery
a890ad5274 RM-7027 Audit delete hold 2019-11-06 16:33:38 +00:00
Sara Aspery
ece61ee5f1 RM-7026 Updated hold name display property 2019-11-06 16:00:53 +00:00
cagache
6b8717ad90 removed unused imports 2019-11-06 17:19:41 +02:00
cagache
80c629b5d2 Refactored audit tests and holds api 2019-11-06 17:18:23 +02:00
Rodica Sutu
9f36c0ad4b Merge branch 'feature/RM-7020_AllowUpdateOfPropertiesForSystemNamespaceURIRefactor' into 'master'
Resolve RM-7020 "Feature/ allowupdateofpropertiesforsystemnamespaceurirefactor"

Closes RM-7020

See merge request records-management/records-management!1293
2019-11-06 14:01:26 +00:00
Sara Aspery
c86a6a8f78 Merge branch 'master' into feature/RM-7026_Add_HoldCreated_ToAudit 2019-11-06 12:22:36 +00:00
cagache
0c21340edd update method names 2019-11-05 16:45:26 +02:00
Rodica Sutu
02bdf0d92a update java docs & fix sonar "Mutable members should not be stored or returned directly" from PropertyModificationAllowedCheck class 2019-11-05 16:43:57 +02:00
cagache
632e185fc2 RM-7033 Automate tests for Audit create, delete, add to, and remove from holds 2019-11-05 16:34:36 +02:00
Rodica Sutu
9e62b9a858 code reviews changes and couple sonar fixes 2019-11-05 11:43:32 +02:00
Rodica Sutu
77f607ed95 Merge branch 'master' of https://git.alfresco.com/records-management/records-management into feature/RM-7020_AllowUpdateOfPropertiesForSystemNamespaceURIRefactor 2019-11-05 11:37:56 +02:00
Roxana Lucanu
d9370c6e2e Merge branch 'feature/RM-7034_AddPoliciesForHeldContent' into 'master'
Resolve RM-7034 "Feature/ addpoliciesforheldcontent"

Closes RM-7034

See merge request records-management/records-management!1284
2019-11-05 09:25:40 +00:00
Roxana Lucanu
bf860c8944 RM-7034 style changes 2019-11-05 10:32:16 +02:00
Rodica Sutu
f54ab26b88 fix the case when before and after values are null 2019-11-04 17:42:25 +02:00
Rodica Sutu
9bbb0b3516 refactor the code to fix the sonar issue "Refactor this method to reduce its Cognitive Complexity from 21 to the 15 allowed." 2019-11-04 17:24:09 +02:00
cagache
e48de60170 removed duplicate methods 2019-11-04 16:59:49 +02:00
Roxana Lucanu
04a190459a RM-7034 Fixed unit tests and split class for add/remove from hold tests. 2019-11-04 16:40:18 +02:00
Roxana Lucanu
9d9a0af5cf RM-7034 Merged master 2019-11-04 12:44:38 +02:00
Roxana Lucanu
b998ed9cd9 RM-7034 Added tests 2019-11-04 12:23:22 +02:00
Rodica Sutu
f05afb2399 Merge branch 'master' of https://git.alfresco.com/records-management/records-management into feature/RM-7020_AlowUpdateOfPropertiesForSystemNameSpaceUri 2019-11-04 11:47:37 +02:00
Rodica Sutu
671d6b954c add unit tests 2019-11-04 11:39:35 +02:00
Sara Aspery
3536d4d571 Merge branch 'master' into 'feature/RM-7026_Add_HoldCreated_ToAudit'
# Conflicts:
#   rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServicePolicies.java
#   rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/CreateHoldTest.java
#   rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/DeleteHoldTest.java
2019-11-04 07:22:27 +00:00
Sara Aspery
6b3f0c2431 RM-7026 Audit Create Hold updates 2019-11-04 07:08:32 +00:00
Ramona Popa
beaf9404b0 Merge branch 'feature/RM-6860_AddHoldServicePolicies' into 'master'
RM-6860: Add hold service policies

Closes RM-6860

See merge request records-management/records-management!1279
2019-11-03 06:47:29 +00:00
Ramona Popa
8c25f6bec7 RM-6860: Add hold service policies
- Added HoldServicePolicies interface
2019-11-03 06:47:29 +00:00
Claudia Agache
dca67b7016 Merge branch 'feature/RM-7017_ActiveHoldsDescription_no' into 'master'
Updated Active Holds description to include active content

Closes RM-7017

See merge request records-management/records-management!1290
2019-11-01 13:44:09 +00:00
cagache
1530e25fe2 Updated strings to not contain "active" 2019-11-01 13:00:45 +02:00
cagache
751dfb3578 Remove unused service 2019-11-01 10:53:08 +02:00
Rodica Sutu
c33e703be9 add a list of namespace URIs for properties, which should be always editable for a frozen node 2019-11-01 09:51:48 +02:00
Tom Page
cb9bc19465 Merge branch 'feature/UpdateDockerPlugin' into 'master'
Update docker plugin to 0.31.0.

See merge request records-management/records-management!1288
2019-10-31 13:51:08 +00:00
Roxana Lucanu
02a7f5e50a Merge 'feature/RM-7035_AddPoliciesForHolds' into feature/RM-7034_AddPoliciesForHeldContent 2019-10-30 10:07:45 +02:00
Sara Aspery
2525ac7803 Merge branch 'feature/RM-7035_AddPoliciesForHolds' into feature/RM-7026_Add_HoldCreated_ToAudit 2019-10-29 15:01:33 +00:00
Ramona Popa
fb49ee3eec Merge branch 'master' into feature/RM-7035_AddPoliciesForHolds 2019-10-29 16:06:50 +02:00
Ramona Popa
5b7bf43044 RM-7035: Add policies for holds
- fixed tests for deleteHold policies
2019-10-29 16:02:40 +02:00
Tom Page
1048225354 Update docker plugin to 0.31.0.
This fixes a problem I was seeing locally with:
> Error getting the version of the configured credential helper
> [Process 'docker-credential-secretservice version' exited with status 1]
2019-10-29 11:51:03 +00:00
Ross Gale
9b5378fb79 RM-6930 adding permissions check for active content in holds defore deletion 2019-10-29 11:43:18 +00:00
Roxana Lucanu
3ff7fb43d0 RM-7034 add policies for held content 2019-10-29 11:37:18 +02:00
Tom Page
ce6cb9e141 Merge branch 'feature/jRebelHotReloading' into 'master'
Add support for jRebel hot reloading.

See merge request records-management/records-management!1278
2019-10-28 14:54:24 +00:00
Sara Aspery
3aa3c8551a RM-7026 add hold created to audit - without audit descriptions 2019-10-28 12:45:06 +00:00
Roxana Lucanu-Ghetu
5f42f53cb1 Merge 'origin/master' into feature/RM-7034_AddPoliciesForHeldContent 2019-10-28 11:16:41 +02:00
Rodica Sutu
a3450f74cf Merge branch 'feature/RM-7012_ActionNameInListOfValuesForAudit' into 'master'
RM-7012

See merge request records-management/records-management!1280
2019-10-28 06:57:46 +00:00
Ramona Popa
5c6c3a395c RM-7035: Add policies for holds
- fix other tests
2019-10-25 16:20:47 +03:00
Rodica Sutu
3b0103d8bc Merge branch 'feature/RM-7043_UpgradeApacheCommonsCompress' into 'master'
RM-7043

See merge request records-management/records-management!1281
2019-10-25 14:02:08 +01:00
Ramona Popa
adc39da95a RM-7035: Add policies for holds
- some minor formating
   - fix unit test
2019-10-25 15:48:10 +03:00
Ramona Popa
f2f010bc4d RM-7035: Add policies for holds
- implementation for policies
   - integration tests
2019-10-25 12:41:09 +03:00
Rodica Sutu
ee929077b9 Update the version for org.apache.commons:commons-compress to 1.19 (fix the security vulnerability alert from github) 2019-10-25 12:21:28 +03:00
Rodica Sutu
d562667ee3 move the actions property file in module-context.xml as the audit events that take the action name are loaded at bootstrap 2019-10-25 11:35:02 +03:00
Ramona Popa
39fe03efc8 RM-6860: Add hold service policies
- Added HoldServicePolicies interface
2019-10-24 11:00:29 +03:00
Rodica Sutu
d597eee1d8 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
2019-10-24 07:02:16 +01:00
Rodica Sutu
52fef5db6a Merge branch 'feature/RM-7006_UpdateToACS611' of https://git.alfresco.com/records-management/records-management into feature/RM-7006_UpdateToACS611 2019-10-23 10:09:14 +03:00
Rodica Sutu
3d9d8bcabe Merge branch 'master' of https://git.alfresco.com/records-management/records-management into feature/RM-7006_UpdateToACS611 2019-10-23 10:03:44 +03:00
cagache
656bb911b4 Record only merge of version change. 2019-10-22 12:51:18 +03:00
cagache
ee4b05567b Record only merge of version change. 2019-10-22 12:50:20 +03:00
cagache
6691917456 Update version to 3.2.1-SNAPSHOT 2019-10-22 12:48:00 +03:00
alfresco-build
26b00f8505 [maven-release-plugin] prepare for next development iteration 2019-10-22 09:18:49 +01:00
Tom Page
aa3dccd5b5 Add support for jRebel hot reloading.
The java files in the repository can be hot reloaded when started from the share docker-file.
2019-10-18 16:15:47 +01:00
Rodica Sutu
f395f7b035 Merge branch 'master' of https://git.alfresco.com/records-management/records-management into feature/RM-7006_UpdateToACS611 2019-10-17 09:30:54 +03:00
cagache
d90b74c80c Revert "Try to use docker build arguments"
This reverts commit 873ac9ef
2019-10-15 09:11:32 +03:00
cagache
873ac9ef1a Try to use docker build arguments 2019-10-15 08:17:48 +03:00
cagache
c4685a23d1 Merge remote-tracking branch 'remotes/origin/master' into feature/RM-7006_UpdateToACS611 2019-10-14 12:44:57 +03:00
Rodica Sutu
b1a9d59aa9 revert the changes from community as there is no corresponding community release for ACS 6.1.1 2019-10-11 12:53:00 +03:00
Rodica Sutu
e2848f3aef library updates to ones from ACS 6.1.1 2019-10-10 17:26:11 +03:00
Ross Gale
474edcca66 Creating hotfix branch 2019-04-30 14:39:47 +01:00
193 changed files with 6111 additions and 1684 deletions

3
.gitignore vendored
View File

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

View File

@@ -1,68 +0,0 @@
<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,129 +1,6 @@
import:
- source: travis-env-vars.yml
os: linux
dist: xenial
language: java
jdk:
- openjdk11
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"
sudo: false
install: true
script: travis_wait 35 mvn -B clean verify -Dcommunity -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn

View File

@@ -170,3 +170,10 @@ 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.2.0.2</version>
<version>3.3.0.1</version>
<name>Alfresco Governance Services</name>
<url>http://www.alfresco.org/</url>
@@ -15,10 +15,10 @@
</organization>
<scm>
<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.2</tag>
<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>
</scm>
<issueManagement>
@@ -468,7 +468,6 @@
<id>start</id>
<phase>pre-integration-test</phase>
<goals>
<goal>stop</goal>
<goal>start</goal>
</goals>
<configuration>
@@ -532,10 +531,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.8</alfresco-spring-webscripts.version>
<api.explorer.version>6.1.0</api.explorer.version>
<alfresco-spring-webscripts.version>7.9</alfresco-spring-webscripts.version>
<api.explorer.version>6.2.0</api.explorer.version>
<!-- Set this here and override it in the community and enterprise modules. -->
<alfresco.version>0.0</alfresco.version>
<alfresco.min.version>0.0</alfresco.min.version>
<skip.integrationtests>true</skip.integrationtests>
<postgres.version>9.4.12</postgres.version>
@@ -560,8 +559,8 @@
<maven.tomcat.port>8080</maven.tomcat.port>
<jackson.version>2.9.9</jackson.version>
<jackson-databind.version>2.9.9.3</jackson-databind.version>
<fabric8.docker.version>0.25.0</fabric8.docker.version>
<jackson-databind.version>2.9.10.1</jackson-databind.version>
<fabric8.docker.version>0.31.0</fabric8.docker.version>
<mockito.version>1.10.19</mockito.version>
<postgresql.version>42.2.6</postgresql.version>
<postgresql.port>5432</postgresql.port>
@@ -593,6 +592,7 @@
<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.version}</value>
<value>${alfresco.min.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>1.18</version>
<version>${apache-compress.version}</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.2.0.2</version>
<version>3.3.0.1</version>
</parent>
<licenses>

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-automation</artifactId>
<version>3.2.0.2</version>
<version>3.3.0.1</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<String>();
ArrayList<String> results = new ArrayList<>();
try
{
JSONArray items = result.getJSONArray("items");
@@ -541,7 +541,6 @@ public abstract class BaseAPI
AlfrescoHttpClient client = alfrescoHttpClientFactory.getObject();
T request = requestType.newInstance();
HttpResponse response = null;
JSONObject responseBody = null;
JSONObject returnValues = null;
@@ -555,7 +554,7 @@ public abstract class BaseAPI
}
LOGGER.info("Sending {} request to {}", requestType.getSimpleName(), requestUrl);
LOGGER.info("Request body: {}", requestParams);
response = client.execute(adminUser, adminPassword, request);
HttpResponse response = client.execute(adminUser, adminPassword, request);
LOGGER.info("Response: {}", response.getStatusLine());
try
@@ -587,13 +586,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,7 +41,11 @@ 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");
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");
/** event audited */
public final String event;

View File

@@ -34,6 +34,11 @@ 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";
@@ -42,4 +47,10 @@ 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<RestNodeModel>(this);
return new ModelAssertion<>(this);
}
@Override

View File

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

View File

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

View File

@@ -28,7 +28,6 @@ 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,6 +54,10 @@ 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)}
*/
@@ -122,7 +126,7 @@ public class PojoUtility
}
catch (IOException e)
{
LOGGER.error("Unable to convert the json into a java object.", e.toString());
LOGGER.error("Unable to convert the json into a java object.", e);
}
return obj;
@@ -152,7 +156,7 @@ public class PojoUtility
}
catch (IOException e)
{
LOGGER.error("Unable to convert the json array into a java collection.", e.toString());
LOGGER.error("Unable to convert the json array into a java collection.", e);
}

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,7 +28,6 @@ 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;
@@ -39,8 +38,7 @@ 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.Utility;
import org.apache.chemistry.opencmis.client.api.CmisObject;
import org.alfresco.utility.model.UserModel;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.json.JSONArray;
@@ -81,18 +79,27 @@ public class HoldsAPI extends BaseAPI
* @param holdName the hold name
* @param reason hold reason
* @param description hold description
* @return The HTTP response (or null if no POST call was needed).
* @return The HTTP response.
*/
public HttpResponse createHold(String user, String password,
String holdName, String reason, String description)
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)
{
// 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);
@@ -102,11 +109,7 @@ public class HoldsAPI extends BaseAPI
requestParams.put("prop_cm_description", description);
requestParams.put("prop_rma_holdReason", reason);
// 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;
return doPostJsonRequest(user, password, expectedStatusCode, requestParams, CREATE_HOLDS_API);
}
/**
@@ -142,7 +145,36 @@ public class HoldsAPI extends BaseAPI
}
/**
* Deletes hold
* 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
*
* @param username user's username
* @param password its password
@@ -179,7 +211,10 @@ public class HoldsAPI extends BaseAPI
*/
public HttpResponse addItemsToHolds(String user, String password, List<String> itemNodeRefs, List<String> holdNames)
{
return addItemsToHolds(user, password, SC_OK, itemNodeRefs, 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);
}
/**
@@ -188,13 +223,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 holdNames the list of holds
* @param holdNodeRefs the list of holds
* @return The HTTP response
*/
public HttpResponse addItemsToHolds(String user, String password, int expectedStatus, List<String> itemNodeRefs,
List<String> holdNames)
List<String> holdNodeRefs)
{
final JSONObject requestParams = addOrRemoveToFromHoldJsonObject(user, password, itemNodeRefs, holdNames);
final JSONObject requestParams = addOrRemoveToFromHoldJsonObject(itemNodeRefs, holdNodeRefs);
return doPostJsonRequest(user, password, expectedStatus, requestParams, RM_HOLDS_API);
}
@@ -204,35 +239,30 @@ 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 holdName the hold name
* @param holdNodeRef the hold node ref
* @return The error message
*/
public String addToHoldAndGetMessage(String user, String password, int expectedStatus, String itemNodeRef, String
holdName)
holdNodeRef)
{
final HttpResponse httpResponse = addItemsToHolds(user, password, expectedStatus, Collections.singletonList(itemNodeRef),
Collections.singletonList(holdName));
Collections.singletonList(holdNodeRef));
return APIUtils.extractErrorMessageFromHttpResponse(httpResponse);
}
/**
* Util method to create the request body used when adding items to holds or when removing items from holds
*
* @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
* @param items list of items node refs to be added to holds
* @param holdNodeRefs list of hold node refs for add/remove items
* @return JSONObject fo
*/
private JSONObject addOrRemoveToFromHoldJsonObject(String user, String password, List<String> items, List<String> holdNames)
private JSONObject addOrRemoveToFromHoldJsonObject(List<String> items, List<String> holdNodeRefs)
{
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(holds::put);
holdNodeRefs.forEach(holdNodeRef -> holds.put(getNodeRefSpacesStore() + holdNodeRef));
final JSONObject requestParams = new JSONObject();
requestParams.put("nodeRefs", nodeRefs);
requestParams.put("holds", holds);
@@ -264,7 +294,10 @@ public class HoldsAPI extends BaseAPI
*/
public HttpResponse removeItemsFromHolds(String user, String password, List<String> itemNodeRefs, List<String> holdNames)
{
return removeItemsFromHolds(user, password, SC_OK, itemNodeRefs, 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);
}
/**
@@ -274,13 +307,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 holdNames the list of hold names
* @param holdNodeRefs the list of hold node refs
* @return The HTTP response
*/
public HttpResponse removeItemsFromHolds(String user, String password, int expectedStatus, List<String> itemNodeRefs,
List<String> holdNames)
List<String> holdNodeRefs)
{
final JSONObject requestParams = addOrRemoveToFromHoldJsonObject(user, password, itemNodeRefs, holdNames);
final JSONObject requestParams = addOrRemoveToFromHoldJsonObject(itemNodeRefs, holdNodeRefs);
return doPutJsonRequest(user, password, expectedStatus, requestParams, RM_HOLDS_API);
}
@@ -290,14 +323,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 holdName the hold name
* @param holdNodeRef the hold node ref
* @return The error message
*/
public String removeFromHoldAndGetMessage(String user, String password, int expectedStatus, String itemNodeRef, String
holdName)
holdNodeRef)
{
final HttpResponse httpResponse = removeItemsFromHolds(user, password, expectedStatus, Collections.singletonList(itemNodeRef),
Collections.singletonList(holdName));
Collections.singletonList(holdNodeRef));
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<BasicNameValuePair>();
List<BasicNameValuePair> searchParameters = new ArrayList<>();
searchParameters.add(new BasicNameValuePair("query", query));
searchParameters.add(new BasicNameValuePair("filters", filters));
if (sortby != null)

View File

@@ -0,0 +1,130 @@
/*
* #%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

@@ -0,0 +1,310 @@
/*
* #%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

@@ -0,0 +1,185 @@
/*
* #%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

@@ -0,0 +1,139 @@
/*
* #%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.List;
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.audit.AuditEntry;
import org.alfresco.rest.v0.RMAuditAPI;
import org.alfresco.rest.v0.service.RMAuditService;
import org.alfresco.test.AlfrescoTest;
import org.alfresco.utility.model.GroupModel;
import org.alfresco.utility.model.UserModel;
@@ -57,16 +57,14 @@ import org.testng.annotations.Test;
public class AuditGroupEventsTests extends BaseRMRestTest
{
@Autowired
private RMAuditAPI rmAuditAPI;
private RMAuditService rmAuditService;
private GroupModel testGroup;
private UserModel testUser;
@BeforeClass (alwaysRun = true)
public void cleanAuditLogs()
{
//clean audit logs
rmAuditAPI.clearAuditLog(getAdminUser().getUsername(), getAdminUser().getPassword());
rmAuditService.clearAuditLog();
}
/**
@@ -79,17 +77,10 @@ public class AuditGroupEventsTests extends BaseRMRestTest
{
testGroup = dataGroup.createRandomGroup();
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())));
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")));
}
/**
@@ -104,19 +95,10 @@ public class AuditGroupEventsTests extends BaseRMRestTest
testUser = getDataUser().createRandomTestUser();
dataGroup.usingUser(testUser).addUserToGroup(testGroup);
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"))));
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")));
}
/**
@@ -132,19 +114,10 @@ public class AuditGroupEventsTests extends BaseRMRestTest
dataGroup.usingUser(testUser).addUserToGroup(testGroup);
dataGroup.removeUserFromGroup(testGroup, testUser);
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"))));
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")));
}
/**
@@ -158,17 +131,9 @@ public class AuditGroupEventsTests extends BaseRMRestTest
testGroup = dataGroup.createRandomGroup();
dataGroup.deleteGroup(testGroup);
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"))));
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")));
}
}

View File

@@ -34,11 +34,10 @@ import java.util.List;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.audit.AuditEntry;
import org.alfresco.rest.v0.RMAuditAPI;
import org.alfresco.rest.v0.service.RMAuditService;
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;
/**
@@ -51,14 +50,7 @@ import org.testng.annotations.Test;
public class AuditLoginEventsTests extends BaseRMRestTest
{
@Autowired
private RMAuditAPI rmAuditAPI;
@BeforeClass (alwaysRun = true)
public void cleanAuditLogs()
{
//clean audit logs
rmAuditAPI.clearAuditLog(getAdminUser().getUsername(), getAdminUser().getPassword());
}
private RMAuditService rmAuditService;
/**
* Given I have tried to login using invalid credentials
@@ -68,12 +60,13 @@ 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 = rmAuditAPI.getRMAuditLog(getAdminUser().getUsername(),
getAdminUser().getPassword(), 100, LOGIN_UNSUCCESSFUL.event);
List<AuditEntry> auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(),
LOGIN_UNSUCCESSFUL);
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

@@ -0,0 +1,325 @@
/*
* #%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,18 +29,17 @@ 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.List;
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.audit.AuditEntry;
import org.alfresco.rest.v0.RMAuditAPI;
import org.alfresco.rest.v0.service.RMAuditService;
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;
/**
@@ -52,10 +51,9 @@ import org.testng.annotations.Test;
public class AuditUserEventsTests extends BaseRMRestTest
{
private final String PREFIX = generateTestPrefix(AuditUserEventsTests.class);
private UserModel createUser;
@Autowired
private RMAuditAPI rmAuditAPI;
private RMAuditService rmAuditService;
/**
* Given I have created a new user
@@ -66,30 +64,16 @@ public class AuditUserEventsTests extends BaseRMRestTest
*/
@Test
@AlfrescoTest(jira = "RM-6223")
public void createUserEventIsAudited() throws Exception
public void createUserEventIsAudited()
{
rmAuditService.clearAuditLog();
STEP("Create a new user.");
String userName = "auditCreateUser" + PREFIX;
createUser = getDataUser().createUser(userName);
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());
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")));
}
@AfterClass (alwaysRun = true)

View File

@@ -615,37 +615,6 @@ 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
*
@@ -849,7 +818,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,9 +107,4 @@ 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,6 +26,8 @@
*/
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;
@@ -87,7 +89,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 = "holdName";
private final static String HOLD_NAME = getRandomName("holdName");
private final static String RECORD_FOLDER_NAME_WITH_SPACE = "Folder With Spaces In Name";
private UserModel userFillingPermission, userReadOnlyPermission;
@@ -411,8 +413,7 @@ 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);
@@ -463,6 +464,7 @@ 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,12 +26,13 @@
*/
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;
@@ -108,7 +109,7 @@ public class AddToHoldsTests extends BaseRMRestTest
private ContentActions contentActions;
@BeforeClass (alwaysRun = true)
public void preconditionForAddContentToHold() throws Exception
public void preconditionForAddContentToHold()
{
STEP("Create a hold.");
holdNodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser().getUsername(),
@@ -174,7 +175,7 @@ public class AddToHoldsTests extends BaseRMRestTest
* Valid nodes to be added to hold
*/
@DataProvider (name = "validNodesForAddToHold")
public Object[][] getValidNodesForAddToHold() throws Exception
public Object[][] getValidNodesForAddToHold()
{
//create electronic and nonElectronic record in record folder
RecordCategoryChild recordFolder = createCategoryFolderInFilePlan();
@@ -287,7 +288,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, HOLD);
SC_INTERNAL_SERVER_ERROR, nodeToBeAddedToHold, holdNodeRef);
assertTrue(response.contains(ACCESS_DENIED_ERROR_MESSAGE));
STEP("Check the node is not frozen.");
@@ -345,7 +346,7 @@ public class AddToHoldsTests extends BaseRMRestTest
{
STEP("Add the node to the hold ");
String responseErrorMessage = holdsAPI.addToHoldAndGetMessage(getAdminUser().getUsername(),
getAdminUser().getPassword(), responseCode, itemNodeRef, HOLD);
getAdminUser().getPassword(), responseCode, itemNodeRef, holdNodeRef);
assertTrue(responseErrorMessage.contains(errorMessage),
"Actual error message " + responseErrorMessage + " expected " + errorMessage);
@@ -354,7 +355,7 @@ public class AddToHoldsTests extends BaseRMRestTest
}
@AfterClass (alwaysRun = true)
public void cleanUpAddContentToHold() throws Exception
public void cleanUpAddContentToHold()
{
holdsAPI.deleteHold(getAdminUser().getUsername(), getAdminUser().getPassword(), HOLD);
dataSite.usingAdmin().deleteSite(testSite);

View File

@@ -36,6 +36,7 @@ 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;
@@ -159,7 +160,8 @@ public class PreventActionsOnFrozenContentTests extends BaseRMRestTest
restClient.authenticateUser(getAdminUser()).withCoreAPI().usingNode(contentHeld).updateNodeContent(updatedFile);
STEP("Check the request failed.");
restClient.assertStatusCodeIs(FORBIDDEN);
//TODO change this to FORBIDDEN when REPO-4632 is fixed
restClient.assertStatusCodeIs(INTERNAL_SERVER_ERROR);
restClient.assertLastError().containsSummary("Frozen content can't be updated.");
}
@@ -194,7 +196,7 @@ public class PreventActionsOnFrozenContentTests extends BaseRMRestTest
STEP("Check the request failed.");
assertStatusCode(FORBIDDEN);
getRestAPIFactory().getRmRestWrapper().assertLastError().containsSummary("Frozen nodes can not be copied.");
getRestAPIFactory().getRmRestWrapper().assertLastError().containsSummary("Permission was denied");
}
/**

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() throws Exception
public void preconditionForRemoveContentFromHold()
{
STEP("Create two holds.");
holdNodeRefOne = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser().getUsername(),
HOLD_ONE, HOLD_REASON, HOLD_DESCRIPTION);
String holdNodeRefTwo = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser()
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, HOLD_ONE);
userModel.getPassword(), SC_INTERNAL_SERVER_ERROR, nodeIdToBeRemoved, holdNodeRefOne);
assertTrue(responseNoHoldPermission.contains(ACCESS_DENIED_ERROR_MESSAGE));
STEP("Check node is frozen.");

View File

@@ -137,8 +137,10 @@ 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,6 +31,7 @@ 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;
@@ -41,7 +42,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.AssertJUnit.assertTrue;
import static org.testng.Assert.assertTrue;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.record.Record;
@@ -50,10 +51,11 @@ 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;
@@ -67,19 +69,35 @@ 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();
.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();
}
/**
* Invalid containers where electronic and non-electronic records can be filed
@@ -98,66 +116,63 @@ public class FileRecordsTests extends BaseRMRestTest
};
}
/**
* Returns the ids of unfiled electronic and non-electronic records from Unfiled Records container
*/
@DataProvider (name = "unfiledRecordsFromUnfiledRecordsContainer")
public Object[][] getRecordsFromUnfiledRecordsContainer()
{
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);
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
public void fileRecordIntoExistingFolderFromUnfiledContainer() throws Exception
@Test (dataProvider = "unfiledRecordsFromUnfiledRecordsContainer")
@AlfrescoTest (jira = "RM-7060")
public void fileRecordFromUnfiledContainerToOpenFolder(String unfiledRecordId) 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 recordNonElect = unfiledContainersAPI.createUnfiledContainerChild(nonelectronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS);
// file the record into the folder created
RecordBodyFile recordBodyFile = RecordBodyFile.builder().targetParentId(folderId).build();
Record recordFiled = recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
// file the record to the folder created
Record recordFiled = fileRecordToFolder(unfiledRecordId, targetFolderId);
// check the response status
assertStatusCode(CREATED);
// check the parent id for the record returned
assertEquals(recordFiled.getParentId(),folderId);
assertEquals(recordFiled.getParentId(), 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 is filed to the record folder
assertTrue(isRecordChildOfRecordFolder(unfiledRecordId, targetFolderId), unfiledRecordId + " is not filed to " + targetFolderId);
// 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(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())));
assertFalse(isRecordChildOfUnfiledContainer(unfiledRecordId), unfiledRecordId + " exists in Unfiled Records");
assertTrue(hasAspect(unfiledRecordId, RECORD_SEARCH_ASPECT), "recordSearch aspect is lost after filing!");
}
/**
@@ -166,62 +181,24 @@ public class FileRecordsTests extends BaseRMRestTest
* When I file the unfiled record into the record folder
* Then the record is filed
*/
@Test
public void fileRecordIntoExistingFolderFromUnfiledRecordFolder() throws Exception
@Test (dataProvider = "unfiledRecordsFromUnfiledRecordFolder")
@AlfrescoTest (jira = "RM-7060")
public void fileRecordFromUnfiledRecordFolderToOpenFolder(String unfiledRecordId) throws Exception
{
// 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());
// file the record to the folder created
Record recordFiled = fileRecordToFolder(unfiledRecordId, targetFolderId);
// check the response status
assertStatusCode(CREATED);
// check the parent id for the record returned
assertEquals(recordFiled.getParentId(),folderId);
assertEquals(recordFiled.getParentId(), 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 is filed to the record folder
assertTrue(isRecordChildOfRecordFolder(unfiledRecordId, targetFolderId), unfiledRecordId + " is not filed to " + targetFolderId);
// check the record doesn't exist into unfiled record folder
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())));
assertFalse(isRecordChildOfUnfiledRecordFolder(unfiledRecordId),
unfiledRecordId + " exists in " + unfiledRecordFolderId);
assertTrue(hasAspect(unfiledRecordId, RECORD_SEARCH_ASPECT), "recordSearch aspect is lost after filing!");
}
/**
@@ -231,55 +208,19 @@ public class FileRecordsTests extends BaseRMRestTest
* Then I get an unsupported operation exception
*
*/
@Test
public void fileRecordIntoCloseFolderFromUnfiledContainer() throws Exception
@Test (dataProvider = "unfiledRecordsFromUnfiledRecordsContainer")
public void fileRecordFromUnfiledContainerToClosedFolder(String unfiledRecordId)
{
// get API instances
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
// create a record folder
String folderId = createCategoryFolderInFilePlan().getId();
closeFolder(folderId);
// 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(folderId).build();
recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
// file the record to the closed record folder
fileRecordToFolder(unfiledRecordId, closedFolderId);
// 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 is not filed to the record folder
assertFalse(isRecordChildOfRecordFolder(unfiledRecordId, closedFolderId), unfiledRecordId + " is filed to " + closedFolderId);
// 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())));
assertTrue(isRecordChildOfUnfiledContainer(unfiledRecordId), unfiledRecordId + " doesn't exist in Unfiled Records");
}
/**
@@ -289,56 +230,20 @@ public class FileRecordsTests extends BaseRMRestTest
* Then I get an unsupported operation exception
*
*/
@Test
public void fileRecordIntoCloseFolderFromUnfiledRecordFolder() throws Exception
@Test(dataProvider = "unfiledRecordsFromUnfiledRecordFolder")
public void fileRecordFromUnfiledRecordFolderToClosedFolder(String unfiledRecordId)
{
// 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());
// file the record into the closed folder created
fileRecordToFolder(unfiledRecordId, closedFolderId);
// 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())));
assertFalse(isRecordChildOfRecordFolder(unfiledRecordId, closedFolderId), unfiledRecordId + " is filed to " + closedFolderId);
// check the record exist into unfiled record folder
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())));
assertTrue(isRecordChildOfUnfiledRecordFolder(unfiledRecordId),
unfiledRecordId + " doesn't exist in " + unfiledRecordFolderId);
}
/**
@@ -347,71 +252,34 @@ public class FileRecordsTests extends BaseRMRestTest
* When I file the filed record into the record folder
* Then the record is filed in both locations
*/
@Test
@Bug(id="RM-4578")
public void linkRecordInto() throws Exception
@Test (dataProvider = "unfiledRecordsFromUnfiledRecordsContainer")
@Bug (id = "RM-4578")
public void linkRecordInto(String unfiledRecordId)
{
// 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());
// file the record to the open folder created
Record recordFiled = fileRecordToFolder(unfiledRecordId, targetFolderId);
// check the response status
assertStatusCode(CREATED);
// create the second folder
String folderToLink = createCategoryFolderInFilePlan().getId();
recordBodyFile = RecordBodyFile.builder().targetParentId(folderToLink).build();
// check the response status
// link the record to the second folder
Record recordLink = fileRecordToFolder(unfiledRecordId, folderToLink);
assertStatusCode(CREATED);
// 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));
assertTrue(recordLink.getParentId().equals(targetFolderId));
// check the record is added into the record folder
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
assertTrue(recordFolderAPI.getRecordFolderChildren(parentFolderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordFiled.getId()) &&
c.getEntry().getParentId().equals(parentFolderId)));
assertTrue(recordFolderAPI.getRecordFolderChildren(targetFolderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordFiled.getId()) &&
c.getEntry().getParentId().equals(targetFolderId)));
// check the record doesn't exist into unfiled record container
// check the record has a link in the second folder
assertTrue(recordFolderAPI.getRecordFolderChildren(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)));
.getEntries().stream()
.anyMatch(c -> c.getEntry().getId().equals(recordFiled.getId()) &&
c.getEntry().getParentId().equals(targetFolderId) &&
!c.getEntry().getParentId().equals(folderToLink)));
}
/**
@@ -425,24 +293,77 @@ 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) throws Exception
public void invalidContainerToFile(String containerId)
{
// 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 record into the folder created
RecordBodyFile recordBodyFile = RecordBodyFile.builder().targetParentId(containerId).build();
recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
// file the records to a container that is not a record folder
fileRecordToFolder(recordElectronic.getId(), containerId);
assertStatusCode(BAD_REQUEST);
recordsAPI.fileRecord(recordBodyFile, recordNonElect.getId());
// check the response status
fileRecordToFolder(recordNonElect.getId(), containerId);
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

@@ -0,0 +1,63 @@
/*
* #%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

@@ -0,0 +1,223 @@
/*
* #%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,6 +49,7 @@ 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://github.com/Alfresco/governance-services) (for partners and customers)
* [Enterprise Source Code](https://gitlab.alfresco.com/records-management/records-management) (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.2.0.2</version>
<version>3.3.0.1</version>
</parent>
<licenses>
@@ -75,8 +75,9 @@
<properties>
<spring.version>5.1.8.RELEASE</spring.version>
<alfresco.version>6.1.2-ga</alfresco.version>
<share.version>6.1.0</share.version>
<alfresco.version>6.2.0-ga</alfresco.version>
<alfresco.min.version>6.1</alfresco.min.version>
<share.version>6.2.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,3 +1,6 @@
SOLR6_TAG=1.1.1
POSTGRES_TAG=10.1
ACTIVEMQ_TAG=5.15.6
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

View File

@@ -1,4 +1,9 @@
FROM alfresco/alfresco-content-repository-community:6.1.2-ga
### 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
COPY target/alfresco-governance-services-community-repo-*.amp /usr/local/tomcat/amps/
@@ -10,4 +15,13 @@ 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
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

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 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.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.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 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.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.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 eine Sperre 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.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=Die Sperre konnte nicht gel\u00f6scht werden, da {1} nicht vom Typ {0} ist.
rm.action.delete-not-hold-type=Der Legal Hold 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=Gesperrt
isFrozen.description=Record oder Record-Ordner ist gesperrt.
isFrozen.title=Mit Legal Hold belegt
isFrozen.description=Record oder Record-Ordner mit Legal Hold belegt
# 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=Sperrgrund bearbeiten
editHoldReason.description=Bearbeitet den Sperrgrund
editHoldReason.title=Grund f\u00fcr Legal Hold bearbeiten
editHoldReason.description=Bearbeiten Sie den Grund f\u00fcr den Legal Hold
# Relinquish Hold
relinquishHold.title=Sperre aufheben
relinquishHold.description=Hebt eine Sperre auf
relinquishHold.title=Legal Hold aufheben
relinquishHold.description=Hebt einen Legal Hold 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=Sperrbereich l\u00f6schen
deleteHold.description=Sperrbereich l\u00f6schen
deleteHold.title=Legal Hold l\u00f6schen
deleteHold.description=Legal Hold l\u00f6schen
# Move DM record
move-dm-record.title=Record verschieben
move-dm-record.description=Record verschieben

View File

@@ -13,6 +13,11 @@ 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,6 +13,11 @@ 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,6 +13,11 @@ 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,6 +13,11 @@ 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,6 +13,11 @@ 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,6 +13,11 @@ 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,6 +13,11 @@ 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,6 +13,11 @@ 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,6 +13,11 @@ 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,6 +13,11 @@ 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,6 +13,11 @@ 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=Sperrsteuerung
capability.group.holdControls.title=Legal-Hold-Steuerung
capability.ExtendRetentionPeriodOrFreeze.title=Aufbewahrungsfrist verl\u00e4ngern oder fixieren
capability.Unfreeze.title=Fixierung aufheben
capability.ViewUpdateReasonsForFreeze.title=Aktualisierungsgrund f\u00fcr Fixierung anzeigen
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
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
# Audit
capability.group.audit.title=Audit

View File

@@ -1,9 +1,10 @@
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 active content. Only records, record \
folders or active content can be added to 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-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.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:

View File

@@ -1,8 +1,10 @@
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.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.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,8 +1,10 @@
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 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-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-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,8 +1,10 @@
rm.hold.not-hold={0} n''est pas 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-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-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,8 +1,10 @@
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 attivo. Solo i record, le cartelle di record o i contenuti attivi possono essere aggiunti ad 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-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,8 +1,10 @@
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\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-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-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,8 +1,10 @@
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.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.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,8 +1,10 @@
rm.hold.not-hold={0} is geen 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-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-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,8 +1,10 @@
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 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-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-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,8 +1,10 @@
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\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-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-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,8 +1,10 @@
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\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-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-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 kontaktieren Sie Ihre IT-Abteilung.
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.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=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_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_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=Sperren
rma_recordsmanagement.association.rma_holds.decription=Sperren
rma_recordsmanagement.association.rma_holds.title=Legal Holds
rma_recordsmanagement.association.rma_holds.decription=Legal Holds
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=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_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_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=Sperrgrund
rma_recordsmanagement.property.rma_recordSearchHoldReason.description=Sperrgrund
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_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=Sperrbericht
rmr_recordsmanagementreport.type.rmr_holdReport.description=Records Management Sperrbericht.
rmr_recordsmanagementreport.type.rmr_holdReport.title=Legal-Hold-Bericht
rmr_recordsmanagementreport.type.rmr_holdReport.description=Records Management-Legal-Hold-Bericht.

View File

@@ -1,4 +1,4 @@
rm.hold.name=Sperrbereich
rm.hold.name=Legal Hold
## 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=Gesperrte Records und Record-Ordner
rm.savedsearch.frozenRecordsDesc=Alle derzeit gesperrten Records und Record-Ordner.
rm.savedsearch.frozenRecordsName=Records und Record-Ordner mit Legal Hold
rm.savedsearch.frozenRecordsDesc=Alle derzeit mit einem Legal Hold belegten 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=Sperrbericht
file.report.hold.name=Sperrname
file.report.hold.description=Sperrbeschreibung
file.report.hold.reason=Sperrgrund
file.report.hold.held=Gesperrt
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.createdby=Erstellt von
file.report.createdon=Erstellt am

View File

@@ -732,6 +732,10 @@
<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.holdHoldReportUpdatePatch"
<bean id="rm.holdReportUpdatePatch"
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

@@ -0,0 +1,19 @@
<?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,16 +3,30 @@
<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>
<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">
<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">
select
count(*)
from
@@ -21,7 +35,7 @@
where
prop.qname_id = ? and
prop.string_value = ?
</select>
<!-- Get distinct property values of children for a given property qname -->
@@ -39,10 +53,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
@@ -55,5 +69,42 @@
</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>
</mapper>
<!-- 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>

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="auditedImmediately" value="true"/>
<property name="auditable" value="false"/>
</bean>
<bean id="deleteHold_proxy" parent="rmProxyAction" >

View File

@@ -12,13 +12,16 @@
<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.FilePlanNamePathDataExtractor">
<bean id="org_alfresco_module_rm_namePathExtractor" class="org.alfresco.module.org_alfresco_module_rm.audit.extractor.NamePathDataExtractor">
<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">
@@ -127,4 +130,28 @@
<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,6 +177,11 @@
</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">
@@ -185,6 +190,7 @@
<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,6 +940,8 @@
<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>
@@ -1532,8 +1534,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,7 +630,6 @@
<!-- 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" />
@@ -681,4 +680,21 @@
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=Assoc.0.1
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.removeAssociation=RM.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=3201
version.rm.schema=3300

View File

@@ -0,0 +1,13 @@
<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

@@ -0,0 +1,30 @@
<#--
#%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,21 +22,71 @@ 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
- 445:445
- 143:143
- "21:21"
- 1143:1143
- "21:1221"
- "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:
@@ -57,6 +107,8 @@ 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.2.0.2</version>
<version>3.3.0.1</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.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>
<!-- 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>
<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.lang.exception.ExceptionUtils.getFullStackTrace;
import static org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace;
import java.io.File;
import java.io.InputStream;
@@ -44,6 +44,7 @@ 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;
@@ -81,8 +82,6 @@ import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.json.JSONObject;
import net.sf.acegisecurity.AccessDeniedException;
/**
* RM Caveat Config component impl
*
@@ -1042,7 +1041,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon
sb.append("' to the JSONObject 'listMembers' '");
sb.append(listMembers);
sb.append("': ");
sb.append(getFullStackTrace(error));
sb.append(getStackTrace(error));
throw new AlfrescoRuntimeException(sb.toString());
}
}
@@ -1061,7 +1060,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon
sb.append("' to the JSONObject 'configJSONObject' '");
sb.append(configJSONObject);
sb.append("': ");
sb.append(getFullStackTrace(error));
sb.append(getStackTrace(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.lang.StringUtils;
import org.apache.commons.lang3.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.lang.StringUtils;
import org.apache.commons.lang3.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.lang.StringUtils.leftPad;
import static org.apache.commons.lang3.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.lang.StringUtils#leftPad(String, int)}
* @deprecated As of 2.1, replaced by {@link org.apache.commons.lang3.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.lang.StringUtils;
import org.apache.commons.lang3.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.lang.StringUtils;
import org.apache.commons.lang3.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.lang.StringUtils;
import org.apache.commons.lang3.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.lang.StringUtils;
import org.apache.commons.lang3.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.lang.StringUtils;
import org.apache.commons.lang3.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.lang.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isBlank;
import java.io.IOException;
import java.io.InputStream;

View File

@@ -33,6 +33,7 @@ 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;
@@ -60,6 +61,8 @@ 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;
@@ -81,6 +84,7 @@ 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;
@@ -91,8 +95,7 @@ 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.lang.StringEscapeUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
@@ -136,6 +139,7 @@ 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";
@@ -193,6 +197,10 @@ 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;
@@ -205,6 +213,8 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
private FilePlanService filePlanService;
private NamespaceService namespaceService;
protected CapabilityService capabilityService;
protected PermissionService permissionService;
protected HoldService holdService;
private boolean shutdown = false;
@@ -321,6 +331,24 @@ 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)
*/
@@ -675,7 +703,8 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
/**
* Helper method to remove system properties from maps
*
* @param properties
* @param before properties before event
* @param after properties after event
*/
private void removeAuditProperties(Map<QName, Serializable> before, Map<QName, Serializable> after)
{
@@ -852,219 +881,7 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
}
// define the callback
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);
}
}
};
AuditQueryCallback callback = new AuditTrailQueryCallback(results, writer, reportFormat);
String user = params.getUser();
Long fromTime = getFromDateTime(params.getDateFrom());
@@ -1161,7 +978,7 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
/**
* Gets the start of the from date
* @see org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditServiceImpl.getStartOfDay()
* @see org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditServiceImpl#getStartOfDay(java.util.Date)
*
* @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.
@@ -1203,7 +1020,7 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
/**
* Gets the end of the from date
* @see org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditServiceImpl.getEndOfDay()
* @see org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditServiceImpl#getEndOfDay(java.util.Date)
*
* @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.
@@ -1343,29 +1160,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;" : StringEscapeUtils.escapeHtml(from.toString()));
writer.write(from == null ? "&lt;Not Set&gt;" : escapeHtml4(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;" : StringEscapeUtils.escapeHtml(to.toString()));
writer.write(to == null ? "&lt;Not Set&gt;" : escapeHtml4(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" : StringEscapeUtils.escapeHtml(getPropertyLabel(prop)));
writer.write(prop == null ? "All" : escapeHtml4(getPropertyLabel(prop)));
writer.write("</span>");
writer.write("<span class=\"label\">User:</span>");
writer.write("<span class=\"value\">");
writer.write(params.getUser() == null ? "All" : StringEscapeUtils.escapeHtml(params.getUser()));
writer.write(params.getUser() == null ? "All" : escapeHtml4(params.getUser()));
writer.write("</span>");
writer.write("<span class=\"label\">Event:</span>");
writer.write("<span class=\"value\">");
writer.write(params.getEvent() == null ? "All" : StringEscapeUtils.escapeHtml(getAuditEventLabel(params.getEvent())));
writer.write(params.getEvent() == null ? "All" : escapeHtml4(getAuditEventLabel(params.getEvent())));
writer.write("</span>\n");
writer.write("</div>\n");
@@ -1407,26 +1224,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(StringEscapeUtils.escapeHtml(entry.getTimestamp().toString()));
writer.write(escapeHtml4(entry.getTimestamp().toString()));
writer.write("</span>");
writer.write("<span class=\"label\">User:</span>");
writer.write("<span class=\"value\">");
writer.write(entry.getFullName() != null ?
StringEscapeUtils.escapeHtml(entry.getFullName()) :
StringEscapeUtils.escapeHtml(entry.getUserName()));
escapeHtml4(entry.getFullName()) :
escapeHtml4(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(StringEscapeUtils.escapeHtml(entry.getUserRole()));
writer.write(escapeHtml4(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(StringEscapeUtils.escapeHtml(getAuditEventLabel(entry.getEvent())));
writer.write(escapeHtml4(getAuditEventLabel(entry.getEvent())));
writer.write("</span>\n");
}
writer.write("</div>\n");
@@ -1435,35 +1252,39 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
{
writer.write("<span class=\"label\">Identifier:</span>");
writer.write("<span class=\"value\">");
writer.write(StringEscapeUtils.escapeHtml(entry.getIdentifier()));
writer.write(escapeHtml4(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(StringEscapeUtils.escapeHtml(entry.getNodeType()));
writer.write(escapeHtml4(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 = path;
int idx = path.indexOf('/', 1);
String displayPath;
int idx = path.indexOf(RM_AUDIT_SITES_PATH);
if (idx != -1)
{
displayPath = "/File Plan" + path.substring(idx);
displayPath = path.substring(idx + RM_AUDIT_SITES_PATH.length());
}
else
{
displayPath = path;
}
writer.write("<span class=\"label\">Location:</span>");
writer.write("<span class=\"value\">");
writer.write(StringEscapeUtils.escapeHtml(displayPath));
writer.write(escapeHtml4(displayPath));
writer.write("</span>");
}
writer.write("</div>\n");
if (entry.getChangedProperties() != null)
if (entry.getChangedProperties() != null && !entry.getChangedProperties().isEmpty())
{
writer.write("<table class=\"changed-values-table\" cellspacing=\"0\">");
writer.write("<tr><th>Property</th><th>Previous Value</th><th>New Value</th></tr>");
@@ -1486,17 +1307,17 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
if(DataTypeDefinition.MLTEXT.equals(propDataType))
{
writer.write(values.getFirst() == null ? "&lt;none&gt;" : StringEscapeUtils.escapeHtml(convertToMlText((Map)values.getFirst()).getDefaultValue()));
writer.write(values.getFirst() == null ? "&lt;none&gt;" : escapeHtml4(convertToMlText((Map) values.getFirst()).getDefaultValue()));
writer.write("</td><td>");
writer.write(values.getSecond() == null ? "&lt;none&gt;" : StringEscapeUtils.escapeHtml(convertToMlText((Map)values.getSecond()).getDefaultValue()));
writer.write(values.getSecond() == null ? "&lt;none&gt;" : escapeHtml4(convertToMlText((Map) values.getSecond()).getDefaultValue()));
}
else
{
Serializable oldValue = values.getFirst();
writer.write(oldValue == null ? "&lt;none&gt;" : StringEscapeUtils.escapeHtml(oldValue.toString()));
writer.write(oldValue == null ? "&lt;none&gt;" : escapeHtml4(oldValue.toString()));
writer.write("</td><td>");
Serializable newValue = values.getSecond();
writer.write(newValue == null ? "&lt;none&gt;" : StringEscapeUtils.escapeHtml(newValue.toString()));
writer.write(newValue == null ? "&lt;none&gt;" : escapeHtml4(newValue.toString()));
}
writer.write("</td></tr>");
@@ -1521,12 +1342,6 @@ 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());
@@ -1606,23 +1421,33 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
case "Delete Person":
nodeName = getNodeName(entry.getBeforeProperties(), PROP_USERNAME);
json.put("deletePerson", true);
json.put("noAvailableLink", 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:
@@ -1891,4 +1716,270 @@ 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

@@ -0,0 +1,85 @@
/*
* #%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