Compare commits

..

201 Commits

Author SHA1 Message Date
Damian.Ujma@hyland.com
cd8ef77b3e Increase sleep to 4 minutes 2022-09-06 12:27:56 +02:00
Damian.Ujma@hyland.com
8622e0e102 Init 2022-09-06 11:10:46 +02:00
Travis CI User
69170dde35 [maven-release-plugin][skip ci] prepare for next development iteration 2022-09-04 00:10:18 +00:00
Travis CI User
c848024130 [maven-release-plugin][skip ci] prepare release 17.101 2022-09-04 00:10:15 +00:00
Alfresco CI User
553f78bb1e [force] Force release for 2022-09-04. 2022-09-04 00:03:36 +00:00
Travis CI User
9a3ceb21a8 [maven-release-plugin][skip ci] prepare for next development iteration 2022-09-03 17:43:30 +00:00
Travis CI User
57d0ff62dc [maven-release-plugin][skip ci] prepare release 17.100 2022-09-03 17:43:27 +00:00
mstrankowski
42bd94c1da ACS-3461: Update ATS reference to released 1.5.4-A3 2022-09-03 18:58:02 +02:00
Travis CI User
c5dd6538f8 [maven-release-plugin][skip ci] prepare for next development iteration 2022-09-01 05:40:58 +00:00
Travis CI User
152c036d86 [maven-release-plugin][skip ci] prepare release 17.99 2022-09-01 05:40:55 +00:00
rrajoria
f2055f91dc Reverting googledrive changes 2022-09-01 10:27:18 +05:30
Travis CI User
a1d7f0d479 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-31 14:01:04 +00:00
Travis CI User
8476f01b35 [maven-release-plugin][skip ci] prepare release 17.98 2022-08-31 14:01:01 +00:00
Maciej Pichura
6c4b9e458a ACS-3431 rule set links TAS REST tests (#1342)
* ACS-3431: Initial TAS REST tests for link to rule set.

* ACS-3431: Fixing assertions.

* ACS-3431: Adding rule set assertions, fixing TAS RESTAPI dependency version.

* ACS-3431: Small test refactorings.

* ACS-3431: Small test refactorings.

* ACS-3431: Adding more tests and refactorings.

* ACS-3431: Fixing a TYPO.
2022-08-31 15:25:25 +02:00
Marcin Strankowski
0f99dec012 ACS-3463: Updating AIS and ATC versions (#1348) 2022-08-31 14:45:25 +02:00
Travis CI User
06c7836e70 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-31 09:54:21 +00:00
Travis CI User
2ceb7384bf [maven-release-plugin][skip ci] prepare release 17.97 2022-08-31 09:54:19 +00:00
rrajoria
d848c83a57 Updating google drive version
Updating google drive version (Test only for JDK 17changes)
2022-08-31 14:46:12 +05:30
Kristian Dimitrov
be7572a978 ACS-3352 GET e2es for newly mapped other fields (#1335)
* ACS-3381: GET e2es for newly mapped other fields

* ACS-3381: Fix failing tests after rebase
2022-08-31 09:53:08 +01:00
Jamal Kaabi-Mofrad
ef45aaf9cc Upgraded Keycloak-Client to match the Identity-Service version. (#1344) 2022-08-30 16:47:37 +01:00
Travis CI User
6f834909f6 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-28 00:10:34 +00:00
Travis CI User
b928598bd7 [maven-release-plugin][skip ci] prepare release 17.96 2022-08-28 00:10:32 +00:00
Alfresco CI User
678eeab278 [force] Force release for 2022-08-28. 2022-08-28 00:04:02 +00:00
Travis CI User
45f9bd6569 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-25 15:41:39 +00:00
Travis CI User
23b8c0e7a6 [maven-release-plugin][skip ci] prepare release 17.95 2022-08-25 15:41:37 +00:00
Antonio Felix
9c98f7b0fb Fix/mnt 23087 export of records failing (#1333)
* MNT-23087 - Split the export list into several smaller list for better performance
2022-08-25 15:36:50 +01:00
Travis CI User
6e1d5c81e2 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-25 11:21:43 +00:00
Travis CI User
092d895f6a [maven-release-plugin][skip ci] prepare release 17.94 2022-08-25 11:21:40 +00:00
Maciej Pichura
a568c87571 ACS-3429, ACS-3336: Rule action mappings (create), validations (update) - part 2 (#1332)
* ACS-3429, ACS-3336: Adding initial TAS tests for create rule with multiple actions, adding action parameters mappings and rule/action validations for rule update.

* ACS-3429: Removing duplicated assertion.

* ACS-3429: Changing NodeRef conversions to use only node id.
2022-08-25 12:46:42 +02:00
Kacper Magdziarz
3aac7be11c MNT-23103 - Downloading a document replaces filename having space with + character (#1327)
* MNT-23103 Change encoder for content disposition filename to be consistent with RFC5987.

Add test covering filename encoding.
2022-08-24 15:59:11 +02:00
Travis CI User
700fbce572 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-24 13:43:15 +00:00
Travis CI User
7be96e788b [maven-release-plugin][skip ci] prepare release 17.93 2022-08-24 13:43:12 +00:00
George Evangelopoulos
0af001be2a Support for linking to a single rule set (#1324)
* Support for linking to a single rule set

* ACS-3435: Small fix to get parent  node for rule set.

* ACS-3435: Revert unnecessary change

* ACS-3435: added tests

* ACS-3435: move test assertions

* ACS-3435: adding tests

Co-authored-by: mpichura <maciej.pichura@hyland.com>
2022-08-24 15:58:04 +03:00
Travis CI User
f38a36910f [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-24 11:57:18 +00:00
Travis CI User
972f81ab8b [maven-release-plugin][skip ci] prepare release 17.92 2022-08-24 11:57:16 +00:00
Domenico Sibilio
1bd0dfd114 ACS-3351 Bump Alfresco JLAN to 7.2 (#1334) 2022-08-24 13:14:03 +02:00
Travis CI User
775de0e94c [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-21 00:10:37 +00:00
Travis CI User
78d2ed247a [maven-release-plugin][skip ci] prepare release 17.91 2022-08-21 00:10:35 +00:00
Alfresco CI User
5ca3630398 [force] Force release for 2022-08-21. 2022-08-21 00:03:38 +00:00
Travis CI User
ee7383dcab [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-19 15:10:22 +00:00
Travis CI User
36b3dc25c0 [maven-release-plugin][skip ci] prepare release 17.90 2022-08-19 15:10:18 +00:00
Maciej Pichura
0b94042b6f ACS-3429 post support for actions (#1305)
* ACS-3429: Initial attemp to add action mappings for create rule.

* ACS-3429: Adding rule action validation (TBC).

* ACS-3429: Adding some basic unit tests.

* ACS-3429: Fixing existing unit tests.

* ACS-3429: Adding some unit tests, small fixes.

* ACS-3429: Fixing existing TAS tests.

* ACS-3429: Fixing test after merge from master.

* ACS-3429: Updating TAS REST dependency.

* ACS-3429: Small fixes after review.

* ACS-3429: Refactoring conversion of action parameters + unit tests adjustments.

* ACS-3429: More unit tests for action parameter conversions.

* ACS-3429: More unit tests for action parameter conversions.

* ACS-3429: Removing unused imports.

* ACS-3429: Adding missing bean definition.
2022-08-19 16:29:37 +02:00
Travis CI User
27d3701c8b [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-18 13:53:38 +00:00
Travis CI User
dc0102001f [maven-release-plugin][skip ci] prepare release 17.89 2022-08-18 13:53:36 +00:00
krdabrowski
12bc363bcd ACS-3353: POST support for "other fields" (#1287) 2022-08-18 14:19:39 +01:00
Tom Page
2ab89f0d79 ACS-3280 Is inheritance enabled rule settings. (#1317)
* ACS-3280 REST tests for -isInheritanceEnabled- setting.

* ACS-3280 Allow setting/getting isInheritanceEnabled for folders.

* ACS-3280 E2E tests for negative cases.

* ACS-3280 Unit tests for RuleSettingsImpl. [tas]

* Update to released TAS REST API. [tas]

* ACS-3280 Code review fixes.

* ACS-3280 Use correct version of TAS. [tas]
2022-08-18 10:53:19 +01:00
Travis CI User
807e509859 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-17 08:57:47 +00:00
Travis CI User
403da286e8 [maven-release-plugin][skip ci] prepare release 17.88 2022-08-17 08:57:45 +00:00
mikolajbrzezinski
cc3f8aaff4 ACS-3316 Fix custom models downloading and XSS (#1304)
* Revert "Revert "ACS-3316 Fix HTML sanitisation bypass (#1266)" (#1294)"

This reverts commit 6c407b1ef5.

* ACS-3316 Set node name for download node

* ACS-3316 Update license

Co-authored-by: Damian.Ujma@hyland.com <Damian.Ujma@hyland.com>
2022-08-17 10:14:40 +02:00
George Evangelopoulos
be925ab67d Change exception type (#1316) 2022-08-16 16:44:29 +03:00
Travis CI User
de4ac000dd [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-15 12:59:40 +00:00
Travis CI User
b2b866e0f9 [maven-release-plugin][skip ci] prepare release 17.87 2022-08-15 12:59:38 +00:00
George Evangelopoulos
984bc151af ACS-3290: V1 REST API endpoint for linking to ruleset (#1269)
* ACS-3290: Endpoint for linking to ruleset

* ACS-3290: Small fixes to REST API endpoint definition.

* ACS-3290: Small fixes in bean initialization.

* ACS-3290: Fix changes after rebasing and add exception message

* ACS-3290: Added unit tests

* ACS-3290: Refactoring and moving logic to RulesImpl interface

* ACS-3290: Remove unused imports and refactoring

* ACS-3290: Formatting

Co-authored-by: mpichura <maciej.pichura@hyland.com>
2022-08-15 15:08:40 +03:00
Travis CI User
b057455cde [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-14 00:10:20 +00:00
Travis CI User
40edaccd1a [maven-release-plugin][skip ci] prepare release 17.86 2022-08-14 00:10:18 +00:00
Alfresco CI User
a802a17d92 [force] Force release for 2022-08-14. 2022-08-14 00:03:42 +00:00
Travis CI User
332626421b [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-12 15:16:34 +00:00
Travis CI User
1baf8d6fae [maven-release-plugin][skip ci] prepare release 17.85 2022-08-12 15:16:32 +00:00
Tom Page
4bae0f2060 ACS-3358 Support isShared field. (#1301)
* Use the new include method.

* ACS-3358 Rename the shared field to isShared.

* ACS-3358 Make isShared an optional field.

* ACS-3358 Add TAS tests for the optional isShared field.

* ACS-3358 Upgrade to release version of TAS REST API. [tas]

* ACS-3358 Update test descriptions.

* ACS-3358 Update toString of Rule.
2022-08-12 15:37:57 +01:00
Travis CI User
0c017ac30c [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-11 15:08:22 +00:00
Travis CI User
cc0940e519 [maven-release-plugin][skip ci] prepare release 17.84 2022-08-11 15:08:19 +00:00
dependabot[bot]
0190b9060a Bump email from 1.8 to 1.9 (#1299) 2022-08-11 14:33:55 +00:00
dependabot[bot]
596e964553 Bump cmis from 1.31 to 1.32 (#1300) 2022-08-11 14:01:09 +00:00
dependabot[bot]
5d22e161d7 Bump webdav from 1.6 to 1.7 (#1296) 2022-08-11 13:59:12 +00:00
dependabot[bot]
bb27430f6a Bump dependency.slf4j.version from 1.7.35 to 1.7.36 (#952) 2022-08-11 13:52:38 +00:00
Travis CI User
1af879a7ed [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-11 11:45:25 +00:00
Travis CI User
c029f5afa3 [maven-release-plugin][skip ci] prepare release 17.83 2022-08-11 11:45:22 +00:00
mstrankowski
3b93814d76 Retry tests 2022-08-11 13:07:19 +02:00
mstrankowski
656ecdc41d [skip tests] Retry release 2022-08-11 13:05:41 +02:00
Travis CI User
8150abf8b7 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-11 10:21:56 +00:00
Travis CI User
cab6fd6d2c [maven-release-plugin][skip ci] prepare release 17.82 2022-08-11 10:21:54 +00:00
dependabot[bot]
e45211ad0f Bump ftp from 1.5 to 1.7 (#1297) 2022-08-11 09:48:29 +00:00
Tom Page
414cba0c1a ACS-3361 Upgrade TAS REST API and check nothing is broken. [tas] (#1295) 2022-08-10 16:42:53 +01:00
Travis CI User
75b74a5d77 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-10 13:25:09 +00:00
Travis CI User
d3efea8873 [maven-release-plugin][skip ci] prepare release 17.81 2022-08-10 13:25:05 +00:00
mikolajbrzezinski
6c407b1ef5 Revert "ACS-3316 Fix HTML sanitisation bypass (#1266)" (#1294)
This reverts commit 885f21ff86.
2022-08-10 14:36:25 +02:00
Travis CI User
f7dcbc6551 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-10 10:31:48 +00:00
Travis CI User
ed1ee00cee [maven-release-plugin][skip ci] prepare release 17.80 2022-08-10 10:31:46 +00:00
Tom Page
bba1664fef ACS-3361 Support for inclusionType. (#1286)
* ACS-3361 Support for inclusionType.

* ACS-3361 Update to released version of TAS Rest API. [tas]

* ACS-3361 Better coverage of different inclusion types. [tas]
2022-08-10 10:58:15 +01:00
Travis CI User
d675d58929 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-09 12:38:17 +00:00
Travis CI User
4f37b984be [maven-release-plugin][skip ci] prepare release 17.79 2022-08-09 12:38:14 +00:00
Marcin Strankowski
9d228add35 Update rest-assured version to 5.1.1, link to newer tas-restapi arti… (#1285)
Update rest-assured version to 5.1.1, link to newer  tas-restapi artifact containing changes
2022-08-09 14:01:44 +02:00
Travis CI User
58d9d0b093 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-09 09:59:45 +00:00
Travis CI User
f8d66ec76d [maven-release-plugin][skip ci] prepare release 17.78 2022-08-09 09:59:42 +00:00
mstrankowski
94a47d0368 [skip tests] Trigger version update 2022-08-09 11:52:24 +02:00
Tom Page
8884cc9563 ACS_3362 GET rule set can include optional owningFolder field. (#1280)
* ACS_3362 GET rule set can include optional owningFolder field. [skip ci]

* ACS_3362 Update to use release version of TAS. [tas]

* ACS_3362 Refactor RuleSetLoader into its own class. [tas]
2022-08-09 10:05:14 +01:00
dependabot[bot]
594f02e7cd Bump junrar from 7.5.2 to 7.5.3 (#1281) 2022-08-09 09:04:42 +00:00
kavitshah-gl
cb29f1e9ec Feature/apps 1550 (#1212)
* Adding test for the stage AGS Smoke UI Tests for actions in RM site

* pushed the createCategoriesTest in APPS-1550 brach

* pushed the createCategoriesTest in APPS-1550 branch

* pushed the CreateFoldersTests in APPS-1550 branch

* [ags]

* ~ /\[ags\]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* Revert "~ /\[ags\]"

This reverts commit ed9443e5

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* Adding FoldersDispositionScheduleTests

* Added foldersDispositionScheduleWithGhosting

* Added foldersDispositionScheduleWithoutGhosting

* Added RecordsDispositionScheduleTests and other fixes

* Added RecordsDispositionScheduleWithGhostingTests

* [ags api]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* Revert "[ags api]"

This reverts commit 2153eafc0f.

* Fixed Review Comments [ags]

Co-authored-by: sbisht <shishuraj.bisht@globallogic.com>
2022-08-09 14:31:28 +05:30
Travis CI User
59816bd071 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-09 08:30:29 +00:00
Travis CI User
bb77023e1f [maven-release-plugin][skip ci] prepare release 17.77 2022-08-09 08:30:26 +00:00
mstrankowski
fa7cb58044 Retrigger master build due to nexus failure 2022-08-09 09:54:43 +02:00
Travis CI User
4962ce1111 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-08 15:24:19 +00:00
Travis CI User
20a0bb7194 [maven-release-plugin][skip ci] prepare release 17.76 2022-08-08 15:24:16 +00:00
dependabot[bot]
1e1bebd19c Bump alfresco-messaging-repo from 1.2.19 to 1.2.20 (#1196) 2022-08-08 14:41:57 +00:00
Travis CI User
03dedb4140 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-08 13:02:05 +00:00
Travis CI User
66f6174b87 [maven-release-plugin][skip ci] prepare release 17.75 2022-08-08 13:02:03 +00:00
mikolajbrzezinski
885f21ff86 ACS-3316 Fix HTML sanitisation bypass (#1266)
* ContentGet context file update

* Get mimetype from ContentReader and check if should be forced to downlaod

* Changes according to comments

* Code duplication removal

* Missing spaces, touch-ups to Javadoc and logic

* tests for slingshot

* Tests for contentGet and formatting changes
2022-08-08 14:26:33 +02:00
Tom Page
501d9204a9 ACS-3360 E2E tests for GET rule sets. [tas] (#1264)
* ACS-3360 GET APIs for rule sets.

Move RulesImpl and RuleSetsImpl into their own package.
Split out node validation into a new class.

* ACS-3360 E2E tests for GET rule sets. [tas]

* ACS-3360 GET APIs for rule sets E2E tests.

* ACS-3360 GET APIs for rule sets E2E tests.

* ACS-3360 GET APIs for rule sets E2E tests.

* ACS-3360 Update comment [skip ci][skip tests]

Co-authored-by: Krystian Dabrowski <krystian.dabrowski@hyland.com>
2022-08-08 11:29:03 +01:00
dependabot[bot]
924005e94e Bump jetty-webapp from 8.2.0.v20160908 to 9.4.34.v20201102 in /remote-api (#270)
* Bump jetty-webapp in /remote-api

Upping jetty to 10.0.11 with a few necessary modifications to avoid errors
Swapping charsets to lowercase, adding ignoring of ambiguous link security issues for jetty (since it is only used in 

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: mstrankowski <marcin.strankowski@hyland.com>
2022-08-08 11:59:07 +02:00
Alfresco CI User
3a34c42d2f [force] Force release for 2022-08-07. 2022-08-07 00:03:34 +00:00
Travis CI User
332af85227 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-06 13:46:10 +00:00
Travis CI User
556c13eba0 [maven-release-plugin][skip ci] prepare release 17.74 2022-08-06 13:46:08 +00:00
dependabot[bot]
3caf6bf9f3 Bump alfresco-opencmis-extension from 2.0 to 2.1 (#1277) 2022-08-06 13:07:29 +00:00
Travis CI User
b5fcc5370a [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-06 10:13:41 +00:00
Travis CI User
29007871e8 [maven-release-plugin][skip ci] prepare release 17.73 2022-08-06 10:13:39 +00:00
dependabot[bot]
12df503cc2 Bump restapi from 1.100 to 1.101 (#1279) 2022-08-06 09:22:07 +00:00
Travis CI User
e3a9e9c034 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-06 08:34:50 +00:00
Travis CI User
d116cf397b [maven-release-plugin][skip ci] prepare release 17.72 2022-08-06 08:34:48 +00:00
dependabot[bot]
271c123a00 Bump alfresco-greenmail from 6.2 to 6.4 (#1278) 2022-08-06 08:01:11 +00:00
Travis CI User
5bae1ca9b6 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-06 01:35:04 +00:00
Travis CI User
f84c82c6a2 [maven-release-plugin][skip ci] prepare release 17.71 2022-08-06 01:35:02 +00:00
dependabot[bot]
c639eec1df Bump acs-event-model from 0.0.15 to 0.0.16 (#1274) 2022-08-06 01:03:07 +00:00
Travis CI User
d2e561dc95 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-06 00:37:30 +00:00
Travis CI User
54347fbbee [maven-release-plugin][skip ci] prepare release 17.70 2022-08-06 00:37:28 +00:00
dependabot[bot]
ab0d482179 Bump postgresql from 42.4.0 to 42.4.1 (#1271) 2022-08-06 00:01:23 +00:00
Travis CI User
5fed5292d9 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-05 09:38:41 +00:00
Travis CI User
1e8944a310 [maven-release-plugin][skip ci] prepare release 17.69 2022-08-05 09:38:38 +00:00
Kristian Dimitrov
b97b6751cc ACS-3381: Initial commit (#1272) 2022-08-05 10:04:17 +01:00
Tom Page
af97aca661 ACS-3360 GET APIs for rule sets. (#1263)
ACS-3360 GET APIs for rule sets.

Move RulesImpl and RuleSetsImpl into their own package.
Split out node validation into a new class.
2022-08-04 17:27:51 +02:00
Travis CI User
368acf4724 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-04 05:56:52 +00:00
Travis CI User
2341f0290e [maven-release-plugin][skip ci] prepare release 17.68 2022-08-04 05:56:49 +00:00
pzurek
2e4f5d5726 Revert "Bump dependency.camel.version from 3.15.0 to 3.18.0 (#1200)"
This reverts commit 2285dc1ecb.
2022-08-04 07:21:17 +02:00
Travis CI User
be118c25ba [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-03 09:43:05 +00:00
Travis CI User
601b743388 [maven-release-plugin][skip ci] prepare release 17.67 2022-08-03 09:43:03 +00:00
Travis CI User
3c3c3b2666 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-03 07:27:27 +00:00
Travis CI User
b671e17f03 [maven-release-plugin][skip ci] prepare release 17.66 2022-08-03 07:27:24 +00:00
dependabot[bot]
a08b134ec2 Bump restapi from 1.99 to 1.100 (#1270) 2022-08-03 06:53:32 +00:00
Travis CI User
9795349f9b [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-02 13:48:18 +00:00
Travis CI User
f120ba3a87 [maven-release-plugin][skip ci] prepare release 17.65 2022-08-02 13:48:15 +00:00
dependabot[bot]
2285dc1ecb Bump dependency.camel.version from 3.15.0 to 3.18.0 (#1200)
Bumps `dependency.camel.version` from 3.15.0 to 3.18.0.

Updates `camel-core` from 3.15.0 to 3.18.0

Updates `camel-spring-xml` from 3.15.0 to 3.18.0

Updates `camel-activemq` from 3.15.0 to 3.18.0

Updates `camel-amqp` from 3.15.0 to 3.18.0

Updates `camel-jackson` from 3.15.0 to 3.18.0

Updates `camel-directvm` from 3.15.0 to 3.18.0

Updates `camel-direct` from 3.15.0 to 3.18.0

Updates `camel-management` from 3.15.0 to 3.18.0

Updates `camel-mock` from 3.15.0 to 3.18.0

---
updated-dependencies:
- dependency-name: org.apache.camel:camel-core
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.apache.camel:camel-spring-xml
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.apache.camel:camel-activemq
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.apache.camel:camel-amqp
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.apache.camel:camel-jackson
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.apache.camel:camel-directvm
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.apache.camel:camel-direct
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.apache.camel:camel-management
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.apache.camel:camel-mock
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-02 15:04:54 +02:00
Travis CI User
cbded8f967 [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-02 13:02:59 +00:00
Travis CI User
5e3ee41fce [maven-release-plugin][skip ci] prepare release 17.64 2022-08-02 13:02:57 +00:00
Maciej Pichura
6c9163ce65 ACS-3227: REST API TAS tests for create rule with consumer role. (#1262) 2022-08-02 14:33:08 +02:00
krdabrowski
8a79d3bed1 ACS-3229: Rules v1 REST API - Get rule definition - mapping of conditions (#1252)
ACS-3229: Rules v1 REST API - Get rule definition
- adding mapping of "conditions"
- fixing trigger constants - uppercase -> lowercase
- fixing booleanMode - uppercase -> lowercase
2022-08-02 14:10:52 +02:00
Travis CI User
f1c588f1da [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-02 08:54:43 +00:00
Travis CI User
f38902ede9 [maven-release-plugin][skip ci] prepare release 17.63 2022-08-02 08:54:40 +00:00
dependabot[bot]
5f1cf5ef60 Bump docker-maven-plugin from 0.40.1 to 0.40.2 (#1267) 2022-08-02 08:01:57 +00:00
Travis CI User
2a41c1f14a [maven-release-plugin][skip ci] prepare for next development iteration 2022-08-01 09:31:23 +00:00
Travis CI User
4f0cbd7206 [maven-release-plugin][skip ci] prepare release 17.62 2022-08-01 09:31:20 +00:00
dependabot[bot]
0823d5319c Bump restapi from 1.97 to 1.99 (#1265) 2022-08-01 08:42:43 +00:00
krdabrowski
001e7a4bff ACS-3229: Rules v1 REST API - Get rule definition - mapping of actions (#1245)
ACS-3229: Rules v1 REST API - Get rule definition
- adding mapping of "actions"
2022-08-01 10:35:52 +02:00
Domenico Sibilio
aba89218e6 ACS-3347 Upgrade to Java 17 (#1253)
* Addressing JDK-8189366, JDK-8212114, JDK-8208487, changes to default legacy Locale ISO Code conversions and changes to JVM arguments to allow illegal reflective access
2022-08-01 09:30:56 +02:00
Travis CI User
e533af4ecb [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-31 00:09:26 +00:00
Travis CI User
4a7046211b [maven-release-plugin][skip ci] prepare release 17.61 2022-07-31 00:09:24 +00:00
Alfresco CI User
48e902c556 [force] Force release for 2022-07-31. 2022-07-31 00:04:00 +00:00
Vítor Moreira
e178428624 MNT-22979: removed unused commons-dbcp artefact from activiti (#1231) 2022-07-29 16:08:13 +01:00
Maciej Pichura
7b4f7c9174 ACS-3345 e2e REST API TAS tests delete rule (#1256)
* ACS-3345: REST API TAS tests for delete rule.

* ACS-3345: REST API TAS tests for delete rule.

* ACS-3345: REST API TAS tests for delete rule.

* ACS-3345: Fixing the naming.

* ACS-3345: REST API TAS tests for delete rule.
2022-07-29 14:29:56 +02:00
dependabot[bot]
d84424ee5b Bump dependency.spring.version from 5.3.21 to 5.3.22 (#1221) 2022-07-29 12:24:41 +00:00
dependabot[bot]
a4ad5f9211 Bump utility from 3.0.48 to 3.0.49 (#1229) 2022-07-29 11:57:56 +00:00
dependabot[bot]
9fbdc61d3c Bump maven-assembly-plugin from 3.4.1 to 3.4.2 (#1248) 2022-07-29 10:02:47 +00:00
dependabot[bot]
7db6d372da Bump maven-resources-plugin from 3.2.0 to 3.3.0 (#1246) 2022-07-29 08:28:12 +00:00
dependabot[bot]
c334f14cd2 Bump groovy from 3.0.11 to 3.0.12 (#1247) 2022-07-29 08:23:39 +00:00
dependabot[bot]
d584b3c1a3 Bump mysql-connector-java from 8.0.29 to 8.0.30 (#1250) 2022-07-29 08:15:56 +00:00
Travis CI User
b06a74c5cb [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-28 16:25:00 +00:00
Travis CI User
5b723e9176 [maven-release-plugin][skip ci] prepare release 17.60 2022-07-28 16:24:56 +00:00
Kristian Dimitrov
bf69340e4b ACS-2827: Initial commit (#1259) 2022-07-28 16:50:43 +01:00
Travis CI User
b6aeac0c4e [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-28 14:37:18 +00:00
Travis CI User
c1da01ba6e [maven-release-plugin][skip ci] prepare release 17.59 2022-07-28 14:37:15 +00:00
Sara
ecb0d9a329 Feature/acs 3122 update tomcat to rocky linux8 (#1258)
* update tomcat base image to rockylinux8

* add dockerfile to dependabot

* update packages for rockylinux8

* fix time zone double quotes

* correct dependabot indents

* correct dependabot indents

* corrected nbr pull requests
2022-07-28 15:02:39 +01:00
Travis CI User
c3189adf9f [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-28 11:48:42 +00:00
Travis CI User
8a7b8a7a54 [maven-release-plugin][skip ci] prepare release 17.58 2022-07-28 11:48:39 +00:00
Sara
3d35eed39c Feature/acs 3122 update tomcat to rocky linux8 (#1255)
* update tomcat base image to rockylinux8

* add dockerfile to dependabot

* update packages for rockylinux8
2022-07-28 12:15:00 +01:00
Travis CI User
37afef846f [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-28 08:16:48 +00:00
Travis CI User
57a3fbd2d5 [maven-release-plugin][skip ci] prepare release 17.57 2022-07-28 08:16:46 +00:00
Tom Page
378347ae35 ACS-3214 Unit tests for update rule API. (#1257) 2022-07-28 08:12:08 +01:00
Travis CI User
fc8ec4f993 [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-27 15:51:33 +00:00
Travis CI User
bd404080b0 [maven-release-plugin][skip ci] prepare release 17.56 2022-07-27 15:51:30 +00:00
Tom Page
54ba3ea998 ACS-3214 Fix compilation error introduced by integration of two features. 2022-07-27 16:16:58 +01:00
Tom Page
13ee559a29 ACS-3214 Update rules. (#1254) 2022-07-27 15:16:46 +01:00
Travis CI User
69b6fc4603 [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-27 13:24:19 +00:00
Travis CI User
f1dc07be57 [maven-release-plugin][skip ci] prepare release 17.55 2022-07-27 13:24:17 +00:00
krdabrowski
ac9151ed86 Rules v1 REST API - Get rule definition - mapping of "other fields" (#1244)
ACS-3229: Rules v1 REST API - Get rule definition
- adding mapping of so-called "other fields"
2022-07-27 14:02:08 +02:00
Damian Ujma
71080c9c7d ACS-3306 Upgrade activemq to 5.17.1-jre11-rockylinux8 (#1241)
* ACS-3306 Upgrade activemq to 5.17.X

* ACS-3306 Upgrade activemq to 5.17.X

* ACS-3306 Upgrade activemq to 5.17.X

* ACS-3306 Resolve conflicts
2022-07-27 13:25:03 +02:00
Travis CI User
a929982faf [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-27 10:32:48 +00:00
Travis CI User
5e3d5919a0 [maven-release-plugin][skip ci] prepare release 17.54 2022-07-27 10:32:46 +00:00
dependabot[bot]
98a3161ef0 Bump restapi from 1.94 to 1.97 (#1249) 2022-07-27 08:26:25 +00:00
Tom Page
74bf3146b3 ACS-3346 Require CHANGE permission for POST/DELETE rules. (#1251) 2022-07-27 09:03:59 +01:00
Travis CI User
b272c89791 [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-27 07:40:32 +00:00
Travis CI User
632a86c5b7 [maven-release-plugin][skip ci] prepare release 17.53 2022-07-27 07:40:30 +00:00
dependabot[bot]
958d6b771e Bump api-explorer from 7.2.0 to 7.2.1 (#1233)
Bumps [api-explorer](https://github.com/Alfresco/rest-api-explorer) from 7.2.0 to 7.2.1.
- [Release notes](https://github.com/Alfresco/rest-api-explorer/releases)
- [Commits](https://github.com/Alfresco/rest-api-explorer/compare/7.2.0...7.2.1)

---
updated-dependencies:
- dependency-name: org.alfresco:api-explorer
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-26 10:39:10 -06:00
Travis CI User
b95233b18a [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-26 11:02:22 +00:00
Travis CI User
aa4ec88ef2 [maven-release-plugin][skip ci] prepare release 17.52 2022-07-26 11:02:20 +00:00
Domenico Sibilio
45ecf340f1 ACS-3342 Test with PostgreSQL 14.4 and 13.7 (#1243) 2022-07-26 12:08:29 +02:00
Travis CI User
81830c8ad4 [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-25 14:42:04 +00:00
Travis CI User
37152229fa [maven-release-plugin][skip ci] prepare release 17.51 2022-07-25 14:42:01 +00:00
Tom Page
182afc58c4 ACS-3227 Update FilePlanRuleInheritanceTest to include a title for the rule. 2022-07-25 15:07:31 +01:00
Tom Page
bc658bbc57 Merge feature/FolderRulesMaster into master. 2022-07-25 14:05:41 +01:00
Tom Page
35f81322b1 ACS-3227 Permissions tests for GET rules. [tas] (#1242) 2022-07-25 14:00:49 +01:00
Tom Page
9e0b69bfa4 ACS-3227 Ensure the rule name is set. (#1240) [tas][ags]
* ACS-3227 Ensure the rule name is set. [tas]

* ACS-3227 Update tests that didn't set rule name.

* Update license year for test file.
2022-07-25 12:35:30 +01:00
Travis CI User
5890e28151 [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-24 00:08:06 +00:00
Travis CI User
dfc0c5674c [maven-release-plugin][skip ci] prepare release 17.50 2022-07-24 00:08:04 +00:00
Alfresco CI User
271feb71c9 [force] Force release for 2022-07-24. 2022-07-24 00:03:24 +00:00
Tom Page
eadc398748 ACS-3227 Add some more comprehensive REST tests for creating rules. (#1239) [tas]
* ACS-3227 Add some more comprehensive REST tests for creating rules.

* ACS-3227 Fix rule name in test. [skip ci]
2022-07-22 14:25:19 +01:00
Tom Page
8f2f8cb04c ACS-3227 Simple rules tests. (#1236) [tas]
* ACS-3227 Initial tests for POST rules API.

* ACS-3227 Add sanity tests for getting created rules.

* Update license header year.
2022-07-22 12:10:01 +01:00
Travis CI User
7a2d6b71ac [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-22 09:38:03 +00:00
Tom Page
3f3698f32a ACS-3227 POST Rule Fixes. (#1235)
* ACS-3227 Don't try to load rule set node if using -default-.

It might not exist yet, since it's created along with the first rule.

Also avoid using id of rule before it has been created.

* ACS-3227 Add a hard-coded action while we don't support supplying actions in the POST.
2022-07-21 13:36:17 +01:00
Maciej Pichura
366796947f ACS-3220 Folder rules delete rule v1 API (#1232)
* ACS-3220: Delete single folder rule.

* ACS-3220: Delete single folder rule - adding more negative unit tests.

* ACS-3220: Delete single folder rule - fixing review comments.
2022-07-21 14:27:58 +02:00
Tom Page
84f7726cbd ACS-3225 REST API to create one or more rules. (#1216) [tas]
* ACS-3225: Folder Rules v1 REST API - Create Rule

* ACS-3225 Create one or more rules within a folder/rule set.

* ACS-3225 Update ExtendedRuleServiceImpl in AGS to match new interface.

* ACS-3225 Code review fixes.

Make RuleBuilder an inner class, add documentation to API and rename method to createRules.

Co-authored-by: Krystian Dabrowski <krystian.dabrowski@hyland.com>
2022-07-20 10:23:30 +01:00
Tom Page
06f0f181df ACS-3225 Add license header to new test file. [skip ci] 2022-07-20 09:51:21 +01:00
Tom Page
741aa6948f ACS-3225 Get rules REST tests. (#1228)
* ACS-3225 REST tests for getting one or more rules.

* ACS-3225 Update TAS REST API.

* ACS-3225 [tas] Include new REST tests.
2022-07-20 09:45:01 +01:00
Tom Page
8618e11a33 ACS-3225 Include TAS changes for rules. (#1227) 2022-07-19 15:22:00 +01:00
133 changed files with 12340 additions and 2088 deletions

View File

@@ -158,3 +158,9 @@ updates:
- "8.16"
registries:
- maven-repository-artifacts-alfresco-com-nexus-content-groups-int
- package-ecosystem: "docker"
directory: "packaging/docker-alfresco/"
schedule:
interval: "daily"
time: "22:00"
timezone: Africa/Abidjan

11
.github/workflows/hackathon.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
name: Hackathon
on:
push:
jobs:
sleep:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: sleep 240

View File

@@ -1,7 +1,7 @@
---
dist: focal
language: java
jdk: openjdk11
jdk: openjdk17
services:
- docker
@@ -69,8 +69,8 @@ jobs:
if: commit_message !~ /\[skip repo\]/
install: skip
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:14.4 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:${TRANSFORMERS_TAG}
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=AppContext01TestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
@@ -78,16 +78,16 @@ jobs:
if: commit_message !~ /\[skip repo\]/
install: skip
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:14.4 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=AppContext02TestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - AppContext03TestSuite"
if: commit_message !~ /\[skip repo\]/
install: skip
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:14.4 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:${TRANSFORMERS_TAG}
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=AppContext03TestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
@@ -95,8 +95,8 @@ jobs:
if: commit_message !~ /\[skip repo\]/
install: skip
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:14.4 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:${TRANSFORMERS_TAG}
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=AppContext04TestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
@@ -104,8 +104,8 @@ jobs:
if: commit_message !~ /\[skip repo\]/
install: skip
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:14.4 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
- mkdir -p "${HOME}/tmp"
- cp repository/src/test/resources/realms/alfresco-realm.json "${HOME}/tmp"
- export HOST_IP=$(hostname -I | cut -f1 -d' ')
@@ -116,8 +116,8 @@ jobs:
if: commit_message !~ /\[skip repo\]/
install: skip
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:14.4 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:${TRANSFORMERS_TAG}
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=AppContext06TestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
@@ -125,8 +125,8 @@ jobs:
if: commit_message !~ /\[skip repo\]/
install: skip
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:14.4 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:${TRANSFORMERS_TAG}
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=AppContextExtraTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
@@ -134,8 +134,8 @@ jobs:
if: commit_message !~ /\[skip repo\]/
install: skip
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:14.4 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:${TRANSFORMERS_TAG}
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=MiscContextTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
@@ -143,8 +143,8 @@ jobs:
if: commit_message !~ /\[skip repo\]/
install: skip
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:14.4 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=SearchTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco -Dindex.subsystem.name=solr6
- name: "Repository - MariaDB 10.2.18 tests"
@@ -152,7 +152,7 @@ jobs:
install: skip
before_script:
- docker run -d -p 3307:3306 --name mariadb -e MYSQL_ROOT_PASSWORD=alfresco -e MYSQL_USER=alfresco -e MYSQL_DATABASE=alfresco -e MYSQL_PASSWORD=alfresco mariadb:10.2.18 --transaction-isolation=READ-COMMITTED --max-connections=300 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.name=alfresco -Ddb.url=jdbc:mariadb://localhost:3307/alfresco?useUnicode=yes\&characterEncoding=UTF-8 -Ddb.username=alfresco -Ddb.password=alfresco -Ddb.driver=org.mariadb.jdbc.Driver
- name: "Repository - MariaDB 10.4 tests"
@@ -160,7 +160,7 @@ jobs:
install: skip
before_script:
- docker run -d -p 3307:3306 --name mariadb -e MYSQL_ROOT_PASSWORD=alfresco -e MYSQL_USER=alfresco -e MYSQL_DATABASE=alfresco -e MYSQL_PASSWORD=alfresco mariadb:10.4 --transaction-isolation=READ-COMMITTED --max-connections=300 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.name=alfresco -Ddb.url=jdbc:mariadb://localhost:3307/alfresco?useUnicode=yes\&characterEncoding=UTF-8 -Ddb.username=alfresco -Ddb.password=alfresco -Ddb.driver=org.mariadb.jdbc.Driver
- name: "Repository - MariaDB 10.5 tests"
@@ -168,7 +168,7 @@ jobs:
install: skip
before_script:
- docker run -d -p 3307:3306 --name mariadb -e MYSQL_ROOT_PASSWORD=alfresco -e MYSQL_USER=alfresco -e MYSQL_DATABASE=alfresco -e MYSQL_PASSWORD=alfresco mariadb:10.5 --transaction-isolation=READ-COMMITTED --max-connections=300 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.name=alfresco -Ddb.url=jdbc:mariadb://localhost:3307/alfresco?useUnicode=yes\&characterEncoding=UTF-8 -Ddb.username=alfresco -Ddb.password=alfresco -Ddb.driver=org.mariadb.jdbc.Driver
- name: "Repository - MariaDB 10.6 tests"
@@ -177,7 +177,7 @@ jobs:
install: skip
before_script:
- docker run -d -p 3307:3306 --name mariadb -e MYSQL_ROOT_PASSWORD=alfresco -e MYSQL_USER=alfresco -e MYSQL_DATABASE=alfresco -e MYSQL_PASSWORD=alfresco mariadb:10.6 --transaction-isolation=READ-COMMITTED --max-connections=300 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.name=alfresco -Ddb.url=jdbc:mariadb://localhost:3307/alfresco?useUnicode=yes\&characterEncoding=UTF-8 -Ddb.username=alfresco -Ddb.password=alfresco -Ddb.driver=org.mariadb.jdbc.Driver
- name: "Repository - MySQL 8 tests"
@@ -186,88 +186,47 @@ jobs:
install: skip
before_script:
- docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=alfresco -e MYSQL_USER=alfresco -e MYSQL_DATABASE=alfresco -e MYSQL_PASSWORD=alfresco mysql:8 --transaction-isolation='READ-COMMITTED'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=com.mysql.jdbc.Driver -Ddb.name=alfresco -Ddb.url=jdbc:mysql://localhost:3307/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - PostgreSQL 10.9 tests"
- name: "Repository - PostgreSQL 13.7 tests"
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip db\]/ AND type != pull_request) OR commit_message =~ /\[db\]/
install: skip
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:10.9 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.7 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - PostgreSQL 11.7 tests"
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip db\]/ AND type != pull_request) OR commit_message =~ /\[db\]/
install: skip
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - PostgreSQL 11.12 tests"
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip db\]/ AND type != pull_request) OR commit_message =~ /\[db\]/
install: skip
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.12 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - PostgreSQL 12.4 tests"
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip db\]/ AND type != pull_request) OR commit_message =~ /\[db\]/
install: skip
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:12.4 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - PostgreSQL 12.7 tests"
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip db\]/ AND type != pull_request) OR commit_message =~ /\[db\]/
install: skip
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:12.7 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - PostgreSQL 13.1 tests"
- name: "Repository - PostgreSQL 14.4 tests"
# We only run DB tests on the latest version of PostgreSQL on feature branches
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip db\]/ AND type != pull_request) OR commit_message =~ /\[db\]/
if: commit_message !~ /\[skip db\]/ OR commit_message =~ /\[db\]/ OR commit_message =~ /\[latest db\]/
install: skip
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.1 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - PostgreSQL 13.3 tests"
# We only run DB tests on the latest version of PostgreSQL on feature branches
if: commit_message !~ /\[skip db\]/ OR commit_message =~ /\[latest db\]/
install: skip
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:14.4 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - Messaging tests"
if: commit_message !~ /\[skip repo\]/
install: skip
before_script:
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=CamelRoutesTest,CamelComponentsTest -DfailIfNoTests=false
- name: "Remote-api - AppContext01TestSuite"
if: commit_message !~ /\[skip repo\]/
install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:14.4 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContext01TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Remote-api - AppContext02TestSuite"
if: commit_message !~ /\[skip repo\]/
install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:14.4 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:${TRANSFORMERS_TAG}
script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContext02TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
@@ -275,8 +234,8 @@ jobs:
if: commit_message !~ /\[skip repo\]/
install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:14.4 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:${TRANSFORMERS_TAG}
script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContext03TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
@@ -284,8 +243,8 @@ jobs:
if: commit_message !~ /\[skip repo\]/
install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:14.4 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:${TRANSFORMERS_TAG}
script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContext04TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
@@ -293,8 +252,8 @@ jobs:
if: commit_message !~ /\[skip repo\]/
install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:14.4 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.17.1-jre11-rockylinux8
script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContextExtraTestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "REST API TAS tests part1"
@@ -374,7 +333,7 @@ jobs:
if: commit_message !~ /\[skip repo\]/
install: skip
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:14.4 postgres -c 'max_connections=300'
script: travis_wait 20 mvn -B test -pl :alfresco-share-services -am -Dtest=ShareServicesTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "AGS Unit & Integration Tests 01 (PostgreSQL)"

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-amps</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<modules>
@@ -30,16 +30,20 @@
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- Keeping illegal-access=permit for Java 11 compatibility, even though it has no effect on JDK 17 -->
<argLine>
--illegal-access=permit
--add-opens=java.base/java.lang=ALL-UNNAMED
</argLine>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<!-- Keeping illegal-access=permit for Java 11 compatibility, even though it has no effect on JDK 17 -->
<configuration>
<argLine>
--illegal-access=permit
--add-opens=java.base/java.lang=ALL-UNNAMED
</argLine>
</configuration>
</plugin>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-parent</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<build>
@@ -45,7 +45,7 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-reload4j</artifactId>
<version>1.7.35</version>
<version>${dependency.slf4j.version}</version>
<scope>test</scope>
</dependency>
<dependency>

View File

@@ -74,4 +74,27 @@ public class RecordFoldersAPI extends BaseAPI
return null;
}
public HttpResponse postFolderAction(String user, String password, JSONObject requestParams, String recordFolder) {
String recNodeRef = getNodeRefSpacesStore() + contentService.getNodeRef(user, password, RM_SITE_ID, recordFolder);
try {
requestParams.put("nodeRef", recNodeRef);
return doPostJsonRequest(user, password, SC_OK, requestParams, RM_ACTIONS_API);
}
catch (Exception error) {
LOGGER.error("Unable to extract response parameter", error);
}
return null;
}
public HttpResponse postRecordAction(String user, String password, JSONObject requestParams, String recordId) {
try {
requestParams.put("nodeRef", recordId);
return doPostJsonRequest(user, password, SC_OK, requestParams, RM_ACTIONS_API);
}
catch (JSONException error) {
LOGGER.error("Unable to extract response parameter", error);
}
return null;
}
}

View File

@@ -53,9 +53,12 @@ import static org.springframework.http.HttpStatus.OK;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Date;
import java.util.TimeZone;
import java.util.stream.Collectors;
import lombok.Getter;
@@ -91,6 +94,7 @@ import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.SiteModel;
import org.alfresco.utility.model.UserModel;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.testng.annotations.BeforeClass;
@@ -121,6 +125,8 @@ public class BaseRMRestTest extends RestTest
@Getter(value = PROTECTED)
private SearchAPI searchApi;
protected static final String iso8601_DateFormat="yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
/**
* Asserts the given status code
*
@@ -161,7 +167,7 @@ public class BaseRMRestTest extends RestTest
*/
@Override
@BeforeClass (alwaysRun = true)
public void checkServerHealth() throws Exception
public void checkServerHealth()
{
// Create RM Site if not exist
createRMSiteIfNotExists();
@@ -628,8 +634,8 @@ public class BaseRMRestTest extends RestTest
* Returns search results for the given search term
*
* @param user
* @param term
* @param query language
* @param q
* @param queryLanguage language
* @return
* @throws Exception
*/
@@ -956,5 +962,34 @@ public class BaseRMRestTest extends RestTest
return false;
}
}
/**
* Helper method to get the Previous Date in the YYYY-MM-ddTHH:mm:ss.SSSXXX format
* @param previousDays number of previous days while calculating the date as output
* @return previousDate as String in the ISO 8601 Date Format
*/
protected String getIso8601Date(int previousDays) {
Date date = new Date(System.currentTimeMillis());
Date previousDate = new Date(date.getTime() - previousDays);
// Conversion
SimpleDateFormat sdf= new SimpleDateFormat(iso8601_DateFormat);;
sdf.setTimeZone(TimeZone.getDefault());
return sdf.format(previousDate);
}
/**
* Helper method to provide the Edited Disposition Date Json
* The Edited Disposition Date is modified to previous date so that CUTOFF & DESTROY Steps will be enabled
* @return JsonObject with the format {"name":"editDispositionActionAsOfDate","params":{"asOfDate":{"iso8601":"Previous Date"}}}
*/
protected JSONObject editDispositionDateJson() {
JSONObject requestParams = new JSONObject();
requestParams.put("name","editDispositionActionAsOfDate");
JSONObject params = new JSONObject();
requestParams.put("params",params);
JSONObject asOfDate = new JSONObject();
params.put("asOfDate",asOfDate);
asOfDate.put("iso8601",getIso8601Date(1));
return requestParams;
}
}

View File

@@ -0,0 +1,211 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2022 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.smoke;
import org.alfresco.dataprep.CMISUtil;
import org.alfresco.rest.core.v0.BaseAPI;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.audit.AuditEntry;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.v0.RMRolesAndActionsAPI;
import org.alfresco.rest.v0.RecordsAPI;
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.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import static org.alfresco.rest.core.v0.BaseAPI.NODE_PREFIX;
import static org.alfresco.rest.core.v0.BaseAPI.RM_SITE_ID;
import static org.alfresco.rest.rm.community.model.audit.AuditEvents.DELETE_PERSON;
import static org.alfresco.rest.rm.community.model.audit.AuditEvents.LOGIN_SUCCESSFUL;
import static org.alfresco.rest.rm.community.records.SearchRecordsTests.*;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.junit.Assert.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
/**
* Audit Access tests
* @author Kavit Shah
*/
public class AuditAccessTests extends BaseRMRestTest {
private Optional<UserModel> deletedUser;
private final String TEST_PREFIX = generateTestPrefix(AuditAccessTests.class);
private static final String DELETE_USER_EVENT = "Delete User";
private final String record1 = TEST_PREFIX + "RM-2967 uploaded record";
private final String classifiedRecord = TEST_PREFIX + "RM-2967 classified record";
private final String folderName = TEST_PREFIX + "RM-2967 folder";
private final String categoryName = TEST_PREFIX + "RM-2967 category";
private final String editedCategoryName = "edited " + categoryName;
private final String editedFolderName = "edited " + folderName;
private final String editedRecordName = "edited " + record1;
private final String login_successfull = "Login Successful";
private RecordCategory categoryAll;
@Autowired
private RMRolesAndActionsAPI rmRolesAndActionsAPI;
@Autowired
private RecordsAPI recordsAPI;
@Autowired
private RMAuditService rmAuditService;
@Test(priority = 1)
@AlfrescoTest(jira = "RM-2967")
public void deleteRMUsersShowFullAuditTest() {
createTestPrecondition();
updateCategoryMetadata();
updateFolderMetadata();
updateRecordMetadata();
// delete record category and folder with rm_admin_deleted
rmRolesAndActionsAPI.deleteAllItemsInContainer(deletedUser.get().getUsername(), deletedUser.get().getPassword(),
RM_SITE_ID, editedFolderName);
rmRolesAndActionsAPI.deleteAllItemsInContainer(deletedUser.get().getUsername(), deletedUser.get().getPassword(),
RM_SITE_ID, editedCategoryName);
// delete the user
Optional.of(deletedUser).ifPresent(x -> getDataUser().deleteUser(x.get()));
//check for RM-5235 fix
List<AuditEntry> auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getDataUser().usingAdmin().getAdminUser(),
DELETE_PERSON);
assertTrue("Delete user event not found in the audit log.", auditEntries.stream().anyMatch(
auditEntry -> auditEntry.getEvent().equals(DELETE_USER_EVENT)));
}
@Test(priority = 2)
public void filterEventsByLoginSuccessful()
{
createRMSiteIfNotExists();
List<AuditEntry> auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getDataUser().usingAdmin().getAdminUser(),
LOGIN_SUCCESSFUL);
assertFalse("Audit results should contain at least one Login Successful event",
auditEntries.isEmpty());
assertTrue("Audit results contain only Login Successful events",
auditEntries.stream()
.allMatch(e -> e.getEvent().startsWith(LOGIN_SUCCESSFUL.toString()) || e.getEvent().startsWith(login_successfull)));
}
/**
* Creates the required precondition for the test
* <p/>
* See Precondition in current class JavaDoc
*/
private void createTestPrecondition() {
createRMSiteIfNotExists();
// create "rm deleted user" user if it does not exist and assign it to RM Administrator role
createDeletedUser();
// create category and folder
categoryAll = createCategoryIfDoesNotExist(categoryName,deletedUser.get());
createRecordFolderInCategory(folderName,categoryAll,deletedUser.get());
// upload an electronic record
recordsAPI.uploadElectronicRecord(deletedUser.get().getUsername(), deletedUser.get().getPassword(), getDefaultElectronicRecordProperties(record1), folderName, CMISUtil.DocumentType.TEXT_PLAIN);
// upload another electronic record and classify it
recordsAPI.uploadElectronicRecord(deletedUser.get().getUsername(), deletedUser.get().getPassword(), getDefaultElectronicRecordProperties(classifiedRecord), folderName, CMISUtil.DocumentType.TEXT_PLAIN);
}
private void createDeletedUser() {
// create Deleted User
deletedUser = Optional.ofNullable(getDataUser().createRandomTestUser());
rmRolesAndActionsAPI.assignRoleToUser(
getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(),
deletedUser.get().getUsername(),
ADMIN
);
}
private void updateCategoryMetadata() {
HashMap<BaseAPI.RMProperty, String> categoryProperties = new HashMap<>();
categoryProperties.put(BaseAPI.RMProperty.NAME, editedCategoryName);
categoryProperties.put(BaseAPI.RMProperty.TITLE, "edited " + TITLE);
categoryProperties.put(BaseAPI.RMProperty.DESCRIPTION, "edited " + DESCRIPTION);
// edit some category's properties
String categoryNodeRef = NODE_PREFIX + rmRolesAndActionsAPI.getItemNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(), "/" + categoryName);
rmRolesAndActionsAPI.updateMetadata(deletedUser.get().getUsername(), deletedUser.get().getPassword(), categoryNodeRef, categoryProperties);
}
private void updateFolderMetadata() {
HashMap<BaseAPI.RMProperty, String> folderProperties = new HashMap<>();
folderProperties.put(BaseAPI.RMProperty.NAME, editedFolderName);
folderProperties.put(BaseAPI.RMProperty.TITLE, "edited " + TITLE);
folderProperties.put(BaseAPI.RMProperty.DESCRIPTION, "edited " + DESCRIPTION);
// edit some folder's properties
String folderNodeRef = NODE_PREFIX + rmRolesAndActionsAPI.getItemNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(), "/" + editedCategoryName + "/" + folderName);
rmRolesAndActionsAPI.updateMetadata(deletedUser.get().getUsername(), deletedUser.get().getPassword(), folderNodeRef, folderProperties);
}
private void updateRecordMetadata() {
HashMap<BaseAPI.RMProperty, String> recordProperties = new HashMap<>();
recordProperties.put(BaseAPI.RMProperty.NAME, editedRecordName);
recordProperties.put(BaseAPI.RMProperty.TITLE, "edited " + TITLE);
recordProperties.put(BaseAPI.RMProperty.AUTHOR, "edited author");
recordProperties.put(BaseAPI.RMProperty.DESCRIPTION, "edited " + DESCRIPTION);
// edit some record's properties
String recordName = recordsAPI.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(), editedFolderName, record1);
String recordNodeRef = NODE_PREFIX + rmRolesAndActionsAPI.getItemNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(), "/" + editedCategoryName + "/" + editedFolderName + "/" + recordName);
rmRolesAndActionsAPI.updateMetadata(deletedUser.get().getUsername(), deletedUser.get().getPassword(), recordNodeRef, recordProperties);
}
private RecordCategory createCategoryIfDoesNotExist(String CATEGORY_ALL, UserModel deletedUser) {
return createRootCategory(deletedUser, CATEGORY_ALL);
}
private RecordCategoryChild createRecordFolderInCategory(String FOLDER_SEARCH, RecordCategory recordCategory, UserModel deletedUser) {
return createFolder(deletedUser, recordCategory.getId(), FOLDER_SEARCH);
}
private Map<BaseAPI.RMProperty, String> getDefaultElectronicRecordProperties(String recordName) {
Map<BaseAPI.RMProperty, String> defaultProperties = new HashMap<>();
defaultProperties.put(BaseAPI.RMProperty.NAME, recordName);
defaultProperties.put(BaseAPI.RMProperty.TITLE, TITLE);
defaultProperties.put(BaseAPI.RMProperty.DESCRIPTION, DESCRIPTION);
defaultProperties.put(BaseAPI.RMProperty.CONTENT, TEST_CONTENT);
return defaultProperties;
}
}

View File

@@ -0,0 +1,104 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2022 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.smoke;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
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.rules.ActionsOnRule;
import org.alfresco.rest.rm.community.model.rules.RuleDefinition;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordFolderAPI;
import org.alfresco.rest.v0.RMRolesAndActionsAPI;
import org.alfresco.rest.v0.RulesAPI;
import org.alfresco.test.AlfrescoTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
import java.util.Collections;
import static org.alfresco.rest.core.v0.BaseAPI.NODE_PREFIX;
import static org.alfresco.rest.rm.community.base.TestData.ELECTRONIC_RECORD_NAME;
import static org.alfresco.rest.rm.community.base.TestData.NONELECTRONIC_RECORD_NAME;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.*;
import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.*;
public class BasicRulesIntegrationTests extends BaseRMRestTest {
@Autowired
private RMRolesAndActionsAPI rmRolesAndActionsAPI;
private final static String title = "Rule to complete";
private final static String description = "Rule to describe";
private final String TEST_PREFIX = generateTestPrefix(CreateCategoriesTests.class);
private final String RM_ADMIN = TEST_PREFIX + "rm_admin";
@Autowired
private RulesAPI rulesAPI;
@Test
@AlfrescoTest(jira = "RM-2794")
public void basicRulesIntegration() {
STEP("Create the RM site if doesn't exist");
createRMSiteIfNotExists();
STEP("Create RM Admin user");
rmRolesAndActionsAPI.createUserAndAssignToRole(getAdminUser().getUsername(), getAdminUser().getPassword(), RM_ADMIN,
getAdminUser().getPassword(),
"Administrator");
STEP("Create record categories and record folders");
RecordCategory Category = createRootCategory(getRandomName("recordCategory"));
String recordFolder1 = createRecordFolder(Category.getId(), getRandomName("recFolder")).getId();
//create a rule for completing a record
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description1")
.applyToChildren(true).title(title)
.actions(Collections.singletonList(ActionsOnRule.COMPLETE_RECORD.getActionValue()));
rulesAPI.createRule(getAdminUser().getUsername(), getAdminUser().getPassword(), NODE_PREFIX + Category.getId(), ruleDefinition);
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
//create two electronic record in record folder
String electronicRecordId1 = createElectronicRecord(recordFolder1, ELECTRONIC_RECORD_NAME).getId();
String electronicRecordId2 = createElectronicRecord(recordFolder1, ELECTRONIC_RECORD_NAME).getId();
assertStatusCode(CREATED);
// Update the rules for record Category
rulesAPI.updateRule(getAdminUser().getUsername(), getAdminUser().getPassword(),
NODE_PREFIX + Category.getId(), ruleDefinition.description("description").id(description));
//Delete the root category and rules
deleteRecordCategory(Category.getId());
rulesAPI.deleteAllRulesOnContainer(getAdminUser().getUsername(), getAdminUser().getPassword(), NODE_PREFIX + Category.getId());
}
}

View File

@@ -0,0 +1,125 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2022 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.smoke;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.fileplan.FilePlan;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.v0.RMRolesAndActionsAPI;
import org.alfresco.test.AlfrescoTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
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.data.RandomData.getRandomAlphanumeric;
import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.junit.Assert.assertFalse;
import static org.springframework.http.HttpStatus.OK;
import static org.testng.Assert.assertEquals;
public class CreateCategoriesTests extends BaseRMRestTest {
@Autowired
private RMRolesAndActionsAPI rmRolesAndActionsAPI;
private RecordCategory rootCategory;
private final String TEST_PREFIX = generateTestPrefix(CreateCategoriesTests.class);
private final String RM_ADMIN = TEST_PREFIX + "rm_admin";
private RecordCategory Category1;
private RecordCategory Category2;
private RecordCategory SubCategory1;
private RecordCategory SubCategory2;
@BeforeClass(alwaysRun = true)
public void preconditionForCreateCategoriesTests()
{
STEP("Create the RM site if doesn't exist");
createRMSiteIfNotExists();
STEP("Create RM Admin user");
rmRolesAndActionsAPI.createUserAndAssignToRole(getAdminUser().getUsername(), getAdminUser().getPassword(), RM_ADMIN,
getAdminUser().getPassword(),
"Administrator");
STEP("Create two category");
Category1 = createRootCategory(getRandomName("Category1"));
Category2= createRootCategory(getRandomName("Category2"));
STEP("Create Sub category");
RecordCategoryChild subCategory1 = createRecordCategory(Category1.getId(), getRandomName("subCategory1"));
RecordCategoryChild subCategory2 = createRecordCategory(Category2.getId(), getRandomName("subCategory2"));
}
@Test @AlfrescoTest(jira = "RM-2756")
public void createCategories() throws Exception {
FilePlan filePlan = getRestAPIFactory().getFilePlansAPI().getFilePlan(FILE_PLAN_ALIAS);
STEP("copy category 1 to File Plan.");
getRestAPIFactory().getNodeAPI(toContentModel(Category1.getId())).copy(createBodyForMoveCopy(filePlan.getId()));
STEP("copy category 1 to category 2");
getRestAPIFactory().getNodeAPI(toContentModel(Category1.getId())).copy(createBodyForMoveCopy(Category2.getId()));
String categoryName = "Category name " + getRandomAlphanumeric();
String categoryTitle = "Category title " + getRandomAlphanumeric();
// Create the root record category
RecordCategory Category1 = createRootCategory(categoryName, categoryTitle);
String newCategoryName = "Rename " + categoryName;
// Build the properties which will be updated
RecordCategory recordCategoryUpdated = Category1.builder().name(newCategoryName).build();
// Update the record category
RecordCategory renamedRecordCategory = getRestAPIFactory().getRecordCategoryAPI().updateRecordCategory(recordCategoryUpdated,Category1.getId());
// Verify the status code
assertStatusCode(OK);
// verify renamed component and editTitle component still has this parent
assertEquals(renamedRecordCategory.getParentId(), filePlan.getId());
STEP("move category 1 edited copy to File Plan");
getRestAPIFactory().getNodeAPI(toContentModel(renamedRecordCategory.getId())).move(createBodyForMoveCopy(filePlan.getId()));
assertStatusCode(OK);
// delete All the categories
deleteRecordCategory(Category1.getId());
deleteRecordCategory(Category2.getId());
}
}

View File

@@ -0,0 +1,147 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2022 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.smoke;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.common.ReviewPeriod;
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.recordfolder.RecordFolder;
import org.alfresco.rest.rm.community.model.recordfolder.RecordFolderProperties;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordCategoryAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordFolderAPI;
import org.alfresco.rest.v0.RMRolesAndActionsAPI;
import org.alfresco.test.AlfrescoTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
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.data.RandomData.getRandomAlphanumeric;
import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.*;
public class CreateFoldersTests extends BaseRMRestTest {
@Autowired
private RMRolesAndActionsAPI rmRolesAndActionsAPI;
private final String TEST_PREFIX = generateTestPrefix(CreateCategoriesTests.class);
private final String RM_ADMIN = TEST_PREFIX + "rm_admin";
private RecordCategory Category1;
private RecordCategory Category2;
private RecordCategoryChild recordCategoryChild;
@BeforeClass(alwaysRun = true)
public void preconditionForCreateFolderTests() {
STEP("Create the RM site if doesn't exist");
createRMSiteIfNotExists();
STEP("Create RM Admin user");
rmRolesAndActionsAPI.createUserAndAssignToRole(getAdminUser().getUsername(), getAdminUser().getPassword(), RM_ADMIN,
getAdminUser().getPassword(),
"Administrator");
STEP("Create two category");
Category1 = createRootCategory(getRandomName("Category1"));
Category2 = createRootCategory(getRandomName("Category2"));
// Create a record folder inside the category 1
recordCategoryChild = createRecordFolder(Category1.getId(), getRandomName("recFolder"));
}
@Test
@AlfrescoTest(jira = "RM-2757")
public void createFolders() throws Exception {
// Create record category first
String folderDescription = "The folder description is updated" + getRandomAlphanumeric();
String folderName = "The folder name is updated" + getRandomAlphanumeric();
String folderTitle = "Update title " + getRandomAlphanumeric();
String location = "Location "+ getRandomAlphanumeric();
// Create the record folder properties to update
RecordFolder recordFolder = RecordFolder.builder()
.name(folderName)
.properties(RecordFolderProperties.builder()
.title(folderTitle)
.description(folderDescription)
.vitalRecordIndicator(true)
.reviewPeriod(new ReviewPeriod("month","1"))
.location(location)
.build())
.build();
// Update the record folder
RecordFolder updatedRecordFolder = getRestAPIFactory().getRecordFolderAPI().updateRecordFolder(recordFolder, recordCategoryChild.getId());
// Check the Response Status Code
assertStatusCode(OK);
STEP("copy updated Record in category 1 and category 2");
getRestAPIFactory().getNodeAPI(toContentModel(updatedRecordFolder.getId())).copy(createBodyForMoveCopy(Category1.getId()));
//assertStatusCode(OK);
getRestAPIFactory().getNodeAPI(toContentModel(updatedRecordFolder.getId())).copy(createBodyForMoveCopy(Category2.getId()));
//assertStatusCode(OK);
// Delete the Updated folder
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
String recordFolderId = updatedRecordFolder.getId();
recordFolderAPI.deleteRecordFolder(recordFolderId);
// Check the response status code
assertStatusCode(NO_CONTENT);
// Check the record folder is not found
recordFolderAPI.getRecordFolder(recordFolderId);
// Check the response status code
assertStatusCode(NOT_FOUND);
STEP("move updated Record from category 1 to category 2");
getRestAPIFactory().getNodeAPI(toContentModel(updatedRecordFolder.getId())).move(createBodyForMoveCopy(Category2.getId()));
// move category 2 to category 1
getRestAPIFactory().getNodeAPI(toContentModel(Category2.getId())).move(createBodyForMoveCopy(Category1.getId()));
// Delete the record category
RecordCategoryAPI recordCategoryAPI = getRestAPIFactory().getRecordCategoryAPI();
String recordCategoryId = Category1.getId();
recordCategoryAPI.deleteRecordCategory(recordCategoryId);
// Verify the status code
assertStatusCode(NO_CONTENT);
}
}

View File

@@ -0,0 +1,122 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2022 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.smoke;
import lombok.Getter;
import org.alfresco.dataprep.CMISUtil;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
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.rules.ActionsOnRule;
import org.alfresco.rest.rm.community.model.rules.RuleDefinition;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildEntry;
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI;
import org.alfresco.rest.v0.RulesAPI;
import org.alfresco.test.AlfrescoTest;
import org.alfresco.utility.data.DataContent;
import org.alfresco.utility.data.DataSite;
import org.alfresco.utility.data.DataUserAIS;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.SiteModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import static lombok.AccessLevel.PROTECTED;
import static org.alfresco.rest.core.v0.BaseAPI.NODE_PREFIX;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.CREATED;
public class DeclareDocsAsRecordsOnUpdateRuleNewVersionTests extends BaseRMRestTest {
@Autowired
private DataSite dataSite;
private SiteModel publicSite;
private RecordCategory recordCategory;
@Autowired
private RulesAPI rulesAPI;
@Autowired
protected DataContent dataContent;
@Autowired
@Getter(value = PROTECTED)
protected DataUserAIS dataUser;
private final static String title = "Rule to convert document as record";
@BeforeClass (alwaysRun = true)
public void setUp()
{
publicSite = dataSite.usingAdmin().createPublicRandomSite();
recordCategory = createRootCategory(getRandomName("recordCategory"));
}
@Test
@AlfrescoTest(jira = "RM-1521")
public void declareDocsAsRecordsOnUpdateRuleNewVersion() {
FolderModel testFolder;
STEP("Create test collaboration site to store documents in.");
publicSite = dataSite.usingAdmin().createPublicRandomSite();
STEP("Create a record folder with a DECLARE_AS_RECORD");
RecordCategoryChild folderWithRule = createFolder(recordCategory.getId(), getRandomName("recordFolder"));
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description")
.applyToChildren(true)
.actions(Collections.singletonList(ActionsOnRule.DECLARE_AS_RECORD.getActionValue()));
rulesAPI.createRule(getAdminUser().getUsername(), getAdminUser().getPassword(), NODE_PREFIX + folderWithRule.getId(), ruleDefinition);
STEP("Create a document in the collaboration site");
FileModel testFile = dataContent.usingSite(publicSite)
.usingAdmin()
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
assertStatusCode(CREATED);
// verify the declared record is in Unfilled Records folder
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
List<UnfiledContainerChildEntry> matchingRecords = unfiledContainersAPI.getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS)
.getEntries()
.stream()
.filter(e -> e.getEntry().getId().equals(testFile.getNodeRefWithoutVersion()))
.collect(Collectors.toList());
//delete rm items
deleteRecordCategory(recordCategory.getId());
STEP("Delete the record.");
//delete created collaboration site
dataSite.deleteSite(publicSite);
}
}

View File

@@ -0,0 +1,238 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2022 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.smoke;
import org.alfresco.dataprep.CMISUtil;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
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.recordfolder.RecordFolderCollection;
import org.alfresco.rest.rm.community.model.user.UserRoles;
import org.alfresco.rest.v0.RecordCategoriesAPI;
import org.alfresco.rest.v0.service.RoleService;
import org.alfresco.test.AlfrescoTest;
import org.alfresco.utility.Utility;
import org.alfresco.utility.data.DataContent;
import org.alfresco.utility.data.DataSite;
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.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.util.concurrent.atomic.AtomicReference;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_FILING;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.rest.rm.community.utils.CoreUtil.toContentModel;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.test.util.AssertionErrors.assertTrue;
import static org.testng.Assert.*;
public class FileAsRecordTests extends BaseRMRestTest {
private static final String CATEGORY_MANAGER = "catManager" + generateTestPrefix(FileAsRecordTests.class);
private static final String CATEGORY_ADMIN = "catAdmin" + generateTestPrefix(FileAsRecordTests.class);
private static final String FOLDER_MANAGER = "recordFolder" + generateTestPrefix(FileAsRecordTests.class);
private static final String FOLDER_ADMIN = "recordFolder" + generateTestPrefix(FileAsRecordTests.class);
private UserModel nonRMuser,rmManager;
private SiteModel testSite;
private FileModel document, documentDeclared;
private RecordCategory category_manager, category_admin;
private RecordCategoryChild folder_admin, folder_manager ;
@Autowired
private DataSite dataSite;
@Autowired
private DataContent dataContent;
@Autowired
private RoleService roleService;
@Autowired
private RecordCategoriesAPI recordCategoriesAPI;
/**
* Create preconditions:
* <pre>
* 1. RM site is created
* 2. Two users: user without RM role and a user with RM manager role
* 3. Two Record categories with one folder each
* 4. User with RM MANAGER role has Filling permission over one category
* </pre>
*/
@BeforeClass(alwaysRun = true)
public void preconditionForFileAsRecordRecordTests()
{
STEP("Create the RM site if doesn't exist");
createRMSiteIfNotExists();
STEP("Create a user");
nonRMuser = dataUser.createRandomTestUser("testUser");
STEP("Create a collaboration site");
testSite = dataSite.usingUser(nonRMuser).createPublicRandomSite();
STEP("Create a document with the user without RM role");
document = dataContent.usingSite(testSite)
.usingUser(nonRMuser)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
STEP("Create two categories with two folders");
category_manager = createRootCategory(CATEGORY_MANAGER);
category_admin = createRootCategory(CATEGORY_ADMIN);
folder_admin = createFolder(category_admin.getId(),FOLDER_ADMIN);
folder_manager = createFolder(category_manager.getId(),FOLDER_MANAGER);
STEP("Create an rm user and give filling permission over CATEGORY_MANAGER record category");
RecordCategory recordCategory = new RecordCategory().builder()
.id(category_manager.getId())
.build();
rmManager = roleService.createCollaboratorWithRMRoleAndPermission(testSite, recordCategory,
UserRoles.ROLE_RM_MANAGER, PERMISSION_FILING);
}
/**
* Given I have selected the record folder I want to file my declared record to
* When I confirm the action
* Then the dialog closes
* And the document is now shown as a record in the collaboration site
* And if I navigated to the record folder, as any user who had the right permissions, then I would see the
* record filed
*/
@Test
@AlfrescoTest(jira = "RM-6780")
public void checkFileAsRecordToRecordFolder() throws Exception {
AtomicReference<RecordFolderCollection> apiChildren = new AtomicReference<>();
STEP("Create a document with the user with RM role");
documentDeclared = dataContent.usingSite(testSite).usingUser(rmManager)
.createContent(new FileModel("checkDeclareAndFileToRecordFolder", FileType.TEXT_PLAIN));
STEP("Declare and file into a record folder the document uploaded");
getRestAPIFactory().getActionsAPI(rmManager).declareAndFile(documentDeclared,
Utility.buildPath(CATEGORY_MANAGER, FOLDER_MANAGER));
STEP("Check the file is a record within the collaboration site");
try
{
Utility.sleep(1000, 40000, () ->
{
JSONObject collaboratorSearchJson = getSearchApi().liveSearchForDocuments(rmManager.getUsername(),
rmManager.getPassword(),
documentDeclared.getName());
assertTrue("Rm Manager not able to find the document.", collaboratorSearchJson.getJSONArray("items").length() != 0);
});
}
catch (InterruptedException e)
{
fail("InterruptedException received while waiting for results.");
}
STEP("Check the record is filed into the record folder.");
// Get children from API
// List children from API
try
{
Utility.sleep(1000, 40000, () ->
{
apiChildren.set((RecordFolderCollection) getRestAPIFactory()
.getRecordFolderAPI(rmManager).getRecordFolderChildren(folder_manager.getId(), "include=properties")
.assertThat().entriesListIsNotEmpty().assertThat().entriesListIsNotEmpty());
});
}
catch (InterruptedException e)
{
fail("InterruptedException received while waiting for results.");
}
assertEquals(apiChildren.get()
.getEntries()
.get(0)
.getEntry()
.getProperties()
.getOriginalName(),documentDeclared.getName());
}
/**
* Given I have selected the "File As Record" action
* When I confirm the action without selecting a location to file to
* Then the record is declared in the unfiled folder
*/
@Test
@AlfrescoTest (jira = "RM-6780")
public void fileAsRecordToUnfiledRecordFolder() throws Exception {
STEP("Create a document with the user without RM role");
FileModel inplaceRecord = dataContent.usingSite(testSite).usingUser(rmManager)
.createContent(new FileModel("declareAndFileToIntoUnfiledRecordFolder",
FileType.TEXT_PLAIN));
STEP("Click on Declare and file without selecting a record folder");
getRestAPIFactory().getActionsAPI(rmManager).declareAndFile(inplaceRecord,"");
STEP("Check the file is declared in unfiled record folder");
Assert.assertTrue(isMatchingRecordInUnfiledRecords(inplaceRecord), "Record should be filed to Unfiled Records folder");
}
@AfterClass(alwaysRun = true)
public void cleanUpForFileAsRecordRecordTests() {
STEP("Delete the collaboration site");
dataSite.usingUser(nonRMuser).deleteSite(testSite);
STEP("Empty the trashcan.");
restClient.authenticateUser(nonRMuser).withCoreAPI().usingTrashcan().deleteNodeFromTrashcan(toContentModel(testSite.getId()));
getRestAPIFactory()
.getUnfiledContainersAPI(rmManager)
.getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS)
.getEntries()
.stream()
.forEach(x -> getRestAPIFactory()
.getRecordsAPI()
.deleteRecord(x.getEntry().getId()));
STEP("Cleanup Documents inside folders");
STEP("Delete folders");
getRestAPIFactory().getRecordFolderAPI().deleteRecordFolder(folder_admin.getId());
getRestAPIFactory().getRecordFolderAPI().deleteRecordFolder(folder_manager.getId());
STEP("Delete categories");
recordCategoriesAPI.deleteCategory(getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(), category_manager.getName());
recordCategoriesAPI.deleteCategory(getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(), category_admin.getName());
STEP("Delete Users");
dataUser.deleteUser(nonRMuser);
dataUser.deleteUser(rmManager);
}
}

View File

@@ -0,0 +1,108 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2022 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.smoke;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
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.v0.RecordFoldersAPI;
import org.alfresco.rest.v0.service.DispositionScheduleService;
import org.alfresco.test.AlfrescoTest;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static org.alfresco.rest.rm.community.model.recordcategory.RetentionPeriodProperty.CREATED_DATE;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.alfresco.utility.report.log.Step.STEP;
public class FoldersDispositionScheduleTests extends BaseRMRestTest {
private RecordCategory Category1;
@Autowired
private DispositionScheduleService dispositionScheduleService;
@Autowired
private RecordFoldersAPI recordFoldersAPI;
private final String TEST_PREFIX = generateTestPrefix(FoldersDispositionScheduleTests.class);
private final String folderDisposition = TEST_PREFIX + "RM-2937 folder ghosting";
private final String electronicRecord = "RM-2937 electronic 2 record";
private final String nonElectronicRecord = "RM-2937 non-electronic record";
@BeforeClass(alwaysRun = true)
private void setUp(){
STEP("Create the RM site if doesn't exist");
createRMSiteIfNotExists();
STEP("Create record category");
Category1 = createRootCategory(getRandomName("Title"));
}
@Test
@AlfrescoTest (jira = "RM-2937")
public void foldersDispositionScheduleWithGhosting() {
//create retention schedule
dispositionScheduleService.createCategoryRetentionSchedule(Category1.getName(), false);
// add cut off step
dispositionScheduleService.addCutOffAfterPeriodStep(Category1.getName(), "day|2", CREATED_DATE);
// add destroy step with ghosting
dispositionScheduleService.addDestroyWithGhostingImmediatelyAfterCutOff(Category1.getName());
//create folders
RecordCategoryChild FOLDER_DESTROY = createFolder(getAdminUser(),Category1.getId(),folderDisposition);
Record elRecord = createElectronicRecord(FOLDER_DESTROY.getId(),electronicRecord);
Record nonElRecord = createNonElectronicRecord(FOLDER_DESTROY.getId(),nonElectronicRecord);
// complete records
completeRecord(elRecord.getId());
completeRecord(nonElRecord.getId());
// edit disposition date
recordFoldersAPI.postFolderAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),editDispositionDateJson(),FOLDER_DESTROY.getName());
// cut off the FOLDER_DESTROY
recordFoldersAPI.postFolderAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),FOLDER_DESTROY.getName());
// Destroy the FOLDER_DESTROY
recordFoldersAPI.postFolderAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),new JSONObject().put("name","destroy"),FOLDER_DESTROY.getName());
}
@AfterMethod(alwaysRun = true)
private void deletePreconditions() {
deleteRecordCategory(Category1.getId());
}
}

View File

@@ -0,0 +1,116 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2022 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.smoke;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
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.v0.RecordFoldersAPI;
import org.alfresco.rest.v0.service.DispositionScheduleService;
import org.alfresco.test.AlfrescoTest;
import org.alfresco.utility.Utility;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static org.alfresco.rest.rm.community.model.recordcategory.RetentionPeriodProperty.CREATED_DATE;
import static org.alfresco.rest.rm.community.model.recordcategory.RetentionPeriodProperty.CUT_OFF_DATE;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.alfresco.utility.report.log.Step.STEP;
public class FoldersDispositionScheduleWithoutGhostRecordTests extends BaseRMRestTest {
private RecordCategory Category1;
@Autowired
private DispositionScheduleService dispositionScheduleService;
@Autowired
private RecordFoldersAPI recordFoldersAPI;
private final String TEST_PREFIX = generateTestPrefix(FoldersDispositionScheduleWithoutGhostRecordTests.class);
private final String folderDisposition = TEST_PREFIX + "RM-2937 folder ghosting";
private final String electronicRecord = "RM-2937 electronic 2 record";
private final String nonElectronicRecord = "RM-2937 non-electronic record";
@BeforeClass(alwaysRun = true)
private void setUp(){
STEP("Create the RM site if doesn't exist");
createRMSiteIfNotExists();
STEP("Create record category");
Category1 = createRootCategory(getRandomName("Title"));
}
@Test
@AlfrescoTest(jira="RM-2937")
public void foldersDispositionScheduleWithoutGhosting() {
//create retention schedule
dispositionScheduleService.createCategoryRetentionSchedule(Category1.getName(), false);
// add cut off step
dispositionScheduleService.addCutOffAfterPeriodStep(Category1.getName(), "day|2", CREATED_DATE);
// add destroy step with ghosting
dispositionScheduleService.addDestroyWithoutGhostingAfterPeriodStep(Category1.getName(), "day|1", CUT_OFF_DATE);
//create folders
RecordCategoryChild FOLDER_DESTROY = createFolder(getAdminUser(),Category1.getId(),folderDisposition);
Record elRecord = createElectronicRecord(FOLDER_DESTROY.getId(),electronicRecord);
Record nonElRecord = createNonElectronicRecord(FOLDER_DESTROY.getId(),nonElectronicRecord);
// complete records
completeRecord(elRecord.getId());
completeRecord(nonElRecord.getId());
// edit disposition date
recordFoldersAPI.postFolderAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),editDispositionDateJson(),FOLDER_DESTROY.getName());
// cut off the FOLDER_DESTROY
recordFoldersAPI.postFolderAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),FOLDER_DESTROY.getName());
// edit disposition date
recordFoldersAPI.postFolderAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),editDispositionDateJson(),FOLDER_DESTROY.getName());
Utility.waitToLoopTime(5,"Waiting for Edit Disposition to be processed");
// Destroy the FOLDER_DESTROY
recordFoldersAPI.postFolderAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),new JSONObject().put("name","destroy"),FOLDER_DESTROY.getName());
}
@AfterMethod(alwaysRun = true)
private void deletePreconditions() {
deleteRecordCategory(Category1.getId());
}
}

View File

@@ -0,0 +1,202 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2022 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.smoke;
import org.alfresco.rest.core.v0.RMEvents;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
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.v0.RMRolesAndActionsAPI;
import org.alfresco.rest.v0.RecordFoldersAPI;
import org.alfresco.rest.v0.RecordsAPI;
import org.alfresco.rest.v0.service.DispositionScheduleService;
import org.alfresco.test.AlfrescoTest;
import org.alfresco.utility.Utility;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
import java.io.IOException;
import java.time.Instant;
import static org.alfresco.rest.rm.community.base.TestData.DEFAULT_PASSWORD;
import static org.alfresco.rest.rm.community.model.recordcategory.RetentionPeriodProperty.CUT_OFF_DATE;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.utility.report.log.Step.STEP;
/**
* Contains recordsDispositionScheduleWithoutGhosting test which checks disposition schedule cut off, transfer and destroy without maintaining metadata steps applied to records
* <p/>
* Precondition:
* <p/>
* RM site created, contains an empty category "RM-2801 disposition for records". <p/>
* RM user has RM admin role. <p/>
* A transfer location named "transferred files" is created to which RM user has access
* <p/>
* <img src="doc-files/Disposition Schedule without ghosting.png" alt="Records Disposition Schedule without ghosting" />
*
* @author Kavit Shah
*/
public class RecordsDispositionScheduleTests extends BaseRMRestTest {
/** data prep 6services */
@Autowired
private RMRolesAndActionsAPI rmRolesAndActionsAPI;
@Autowired
private RecordsAPI recordsAPI;
@Autowired
private RecordFoldersAPI recordFoldersAPI;
@Autowired
private DispositionScheduleService dispositionScheduleService;
private RecordCategory Category1;
private final String TEST_PREFIX = generateTestPrefix(RecordsDispositionScheduleTests.class);
private final String RM_ADMIN = TEST_PREFIX + "rm_admin";
private final String recordsCategory = TEST_PREFIX + "RM-2801 category";
private final String folderDisposition = TEST_PREFIX + "RM-2801 folder";
@Test
@AlfrescoTest(jira="RM-2801")
public void recordsDispositionScheduleWithoutGhosting() {
// create test precondition
createTestPrecondition(recordsCategory);
// create disposition schedule
dispositionScheduleService.createCategoryRetentionSchedule(Category1.getName(), true);
// add cut off step
dispositionScheduleService.addCutOffImmediatelyStep(Category1.getName());
// add transfer step
dispositionScheduleService.addTransferAfterEventStep(Category1.getName(),"transferred records","all_allowances_granted_are_terminated");
// add destroy step without retaining metadata
dispositionScheduleService.addDestroyWithoutGhostingAfterPeriodStep(Category1.getName(), "day|1", CUT_OFF_DATE);
// create a folder and an electronic and a non-electronic record in it
RecordCategoryChild FOLDER_DESTROY = createFolder(getAdminUser(),Category1.getId(),folderDisposition);
String electronicRecord = "RM-2801 electronic record";
Record elRecord = createElectronicRecord(FOLDER_DESTROY.getId(), electronicRecord);
String nonElectronicRecord = "RM-2801 non-electronic record";
Record nonElRecord = createNonElectronicRecord(FOLDER_DESTROY.getId(), nonElectronicRecord);
// complete records and cut them off
String nonElRecordName = recordsAPI.getRecordFullName(getAdminUser().getUsername(),
getAdminUser().getPassword(), folderDisposition, nonElectronicRecord);
String elRecordName = recordsAPI.getRecordFullName(getAdminUser().getUsername(),
getAdminUser().getPassword(), folderDisposition, electronicRecord);
// complete records and cut them off
completeRecord(elRecord.getId());
completeRecord(nonElRecord.getId());
String nonElRecordNameNodeRef = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(), nonElRecordName, "/" + Category1.getName() + "/" + folderDisposition);
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),nonElRecordNameNodeRef);
String elRecordNameNodeRef = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordName, "/" + Category1.getName() + "/" + folderDisposition);
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),elRecordNameNodeRef);
// ensure the complete event action is displayed for both events
rmRolesAndActionsAPI.completeEvent(getAdminUser().getUsername(),
getAdminUser().getPassword(), nonElRecordName, RMEvents.ALL_ALLOWANCES_GRANTED_ARE_TERMINATED, Instant.now());
rmRolesAndActionsAPI.completeEvent(getAdminUser().getUsername(),
getAdminUser().getPassword(), elRecordName, RMEvents.ALL_ALLOWANCES_GRANTED_ARE_TERMINATED, Instant.now());
// Create and Complete transfer
HttpResponse nonElRecordNameHttpResponse = recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),new JSONObject().put("name","transfer"),recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(), nonElRecordName, "/" + Category1.getName() + "/" + folderDisposition));
String nonElRecordNameTransferId = getTransferId(nonElRecordNameHttpResponse,nonElRecordNameNodeRef);
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),new JSONObject().put("name","transferComplete"),nonElRecordNameTransferId);
HttpResponse elRecordNameHttpResponse = recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),new JSONObject().put("name","transfer"),recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordName, "/" + Category1.getName() + "/" + folderDisposition));
String elRecordNameTransferId = getTransferId(elRecordNameHttpResponse,elRecordNameNodeRef);
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),new JSONObject().put("name","transferComplete"),elRecordNameTransferId);
// edit the disposition schedule date to current date
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),editDispositionDateJson(),nonElRecordNameNodeRef);
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),editDispositionDateJson(),elRecordNameNodeRef);
Utility.waitToLoopTime(5,"Waiting for Edit Disposition to be processed");
// destroy records
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),new JSONObject().put("name","destroy"),nonElRecordNameNodeRef);
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),new JSONObject().put("name","destroy"),elRecordNameNodeRef);
// delete category
deleteRecordCategory(Category1.getId());
}
private void createTestPrecondition(String categoryName) {
createRMSiteIfNotExists();
// create "rm admin" user if it does not exist and assign it to RM Administrator role
rmRolesAndActionsAPI.createUserAndAssignToRole(
getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(),
RM_ADMIN, DEFAULT_PASSWORD, "Administrator");
// create category
STEP("Create two category");
Category1 = createRootCategory(categoryName,"Title");
}
private String getTransferId(HttpResponse httpResponse,String nodeRef) {
HttpEntity entity = httpResponse.getEntity();
String responseString = null;
try {
responseString = EntityUtils.toString(entity, "UTF-8");
} catch (IOException e) {
throw new RuntimeException(e);
}
JSONObject result = new JSONObject(responseString);
return result
.getJSONObject("results")
.get(nodeRef)
.toString();
}
}

View File

@@ -0,0 +1,200 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2022 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.smoke;
import org.alfresco.rest.core.v0.RMEvents;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
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.v0.RMRolesAndActionsAPI;
import org.alfresco.rest.v0.RecordFoldersAPI;
import org.alfresco.rest.v0.RecordsAPI;
import org.alfresco.rest.v0.service.DispositionScheduleService;
import org.alfresco.test.AlfrescoTest;
import org.alfresco.utility.Utility;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
import java.io.IOException;
import java.time.Instant;
import static org.alfresco.rest.rm.community.base.TestData.DEFAULT_PASSWORD;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.utility.report.log.Step.STEP;
/**
* Contains recordsDispositionScheduleWithGhosting test which checks disposition schedule cut off, transfer and destroy with maintaining record metadata steps applied to records
* <p/>
* Precondition:
* <p/>
* RM site created, contains an empty category "RM-2937 disposition for records with ghosting". <p/>
* RM user has RM admin role. <p/>
* A transfer location named "transferred files with ghosting" is created to which RM user has access
* <p/>
* <img src="doc-files/Disposition Schedule with ghosting.png" alt="Records Disposition Schedule with ghosting" />
*
* @author Kavit Shah
*/
public class RecordsDispositionScheduleWithGhostingTests extends BaseRMRestTest {
/** data prep 6services */
@Autowired
private RMRolesAndActionsAPI rmRolesAndActionsAPI;
@Autowired
private RecordsAPI recordsAPI;
@Autowired
private RecordFoldersAPI recordFoldersAPI;
@Autowired
private DispositionScheduleService dispositionScheduleService;
private RecordCategory Category1;
private final String TEST_PREFIX = generateTestPrefix(RecordsDispositionScheduleTests.class);
private final String RM_ADMIN = TEST_PREFIX + "rm_admin";
private final String recordsCategory = TEST_PREFIX + "RM-2801 category";
private final String folderDisposition = TEST_PREFIX + "RM-2801 folder";
@Test
@AlfrescoTest(jira="RM-2801")
public void recordsDispositionScheduleWithGhosting() {
// create test precondition
createTestPrecondition(recordsCategory);
// create disposition schedule
dispositionScheduleService.createCategoryRetentionSchedule(Category1.getName(), true);
// add cut off step
dispositionScheduleService.addCutOffImmediatelyStep(Category1.getName());
// add transfer step
dispositionScheduleService.addTransferAfterEventStep(Category1.getName(),"transferred records","all_allowances_granted_are_terminated");
// add destroy step without retaining metadata
dispositionScheduleService.addDestroyWithGhostingImmediatelyAfterCutOff(Category1.getName());
// create a folder and an electronic and a non-electronic record in it
RecordCategoryChild FOLDER_DESTROY = createFolder(getAdminUser(),Category1.getId(),folderDisposition);
String electronicRecord = "RM-2801 electronic record";
Record elRecord = createElectronicRecord(FOLDER_DESTROY.getId(), electronicRecord);
String nonElectronicRecord = "RM-2801 non-electronic record";
Record nonElRecord = createNonElectronicRecord(FOLDER_DESTROY.getId(), nonElectronicRecord);
// complete records and cut them off
String nonElRecordName = recordsAPI.getRecordFullName(getAdminUser().getUsername(),
getAdminUser().getPassword(), folderDisposition, nonElectronicRecord);
String elRecordName = recordsAPI.getRecordFullName(getAdminUser().getUsername(),
getAdminUser().getPassword(), folderDisposition, electronicRecord);
// complete records and cut them off
completeRecord(elRecord.getId());
completeRecord(nonElRecord.getId());
String nonElRecordNameNodeRef = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(), nonElRecordName, "/" + Category1.getName() + "/" + folderDisposition);
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),nonElRecordNameNodeRef);
String elRecordNameNodeRef = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordName, "/" + Category1.getName() + "/" + folderDisposition);
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),elRecordNameNodeRef);
// ensure the complete event action is displayed for both events
rmRolesAndActionsAPI.completeEvent(getAdminUser().getUsername(),
getAdminUser().getPassword(), nonElRecordName, RMEvents.ALL_ALLOWANCES_GRANTED_ARE_TERMINATED, Instant.now());
rmRolesAndActionsAPI.completeEvent(getAdminUser().getUsername(),
getAdminUser().getPassword(), elRecordName, RMEvents.ALL_ALLOWANCES_GRANTED_ARE_TERMINATED, Instant.now());
// Create and Complete transfer
HttpResponse nonElRecordNameHttpResponse = recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),new JSONObject().put("name","transfer"),recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(), nonElRecordName, "/" + Category1.getName() + "/" + folderDisposition));
String nonElRecordNameTransferId = getTransferId(nonElRecordNameHttpResponse,nonElRecordNameNodeRef);
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),new JSONObject().put("name","transferComplete"),nonElRecordNameTransferId);
HttpResponse elRecordNameHttpResponse = recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),new JSONObject().put("name","transfer"),recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordName, "/" + Category1.getName() + "/" + folderDisposition));
String elRecordNameTransferId = getTransferId(elRecordNameHttpResponse,elRecordNameNodeRef);
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),new JSONObject().put("name","transferComplete"),elRecordNameTransferId);
// edit the disposition schedule date to current date
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),editDispositionDateJson(),nonElRecordNameNodeRef);
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),editDispositionDateJson(),elRecordNameNodeRef);
Utility.waitToLoopTime(5,"Waiting for Edit Disposition to be processed");
// destroy records
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),new JSONObject().put("name","destroy"),nonElRecordNameNodeRef);
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
getAdminUser().getPassword(),new JSONObject().put("name","destroy"),elRecordNameNodeRef);
// delete category
deleteRecordCategory(Category1.getId());
}
private void createTestPrecondition(String categoryName) {
createRMSiteIfNotExists();
// create "rm admin" user if it does not exist and assign it to RM Administrator role
rmRolesAndActionsAPI.createUserAndAssignToRole(
getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(),
RM_ADMIN, DEFAULT_PASSWORD, "Administrator");
// create category
STEP("Create two category");
Category1 = createRootCategory(categoryName,"Title");
}
private String getTransferId(HttpResponse httpResponse,String nodeRef) {
HttpEntity entity = httpResponse.getEntity();
String responseString = null;
try {
responseString = EntityUtils.toString(entity, "UTF-8");
} catch (IOException e) {
throw new RuntimeException(e);
}
JSONObject result = new JSONObject(responseString);
return result
.getJSONObject("results")
.get(nodeRef)
.toString();
}
}

View File

@@ -0,0 +1,124 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2022 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.smoke;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.record.RecordContent;
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.rules.ActionsOnRule;
import org.alfresco.rest.rm.community.model.rules.RuleDefinition;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainer;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChild;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildProperties;
import org.alfresco.rest.v0.RMRolesAndActionsAPI;
import org.alfresco.rest.v0.RulesAPI;
import org.alfresco.test.AlfrescoTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.alfresco.rest.core.v0.BaseAPI.NODE_PREFIX;
import static org.alfresco.rest.rm.community.base.TestData.ELECTRONIC_RECORD_NAME;
import static org.alfresco.rest.rm.community.base.TestData.NONELECTRONIC_RECORD_NAME;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.*;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.*;
public class UnfiledRecordsRuleTests extends BaseRMRestTest {
@Autowired
private RMRolesAndActionsAPI rmRolesAndActionsAPI;
private final String TEST_PREFIX = generateTestPrefix(CreateCategoriesTests.class);
private final String RM_ADMIN = TEST_PREFIX + "rm_admin";
private RecordCategory Category2;
private RecordCategoryChild Folder2;
@Autowired
private RulesAPI rulesAPI;
@Test
@AlfrescoTest(jira = "RM-2794")
public void unfiledRecordsRule() {
STEP("Create the RM site if doesn't exist");
createRMSiteIfNotExists();
STEP("Create RM Admin user");
rmRolesAndActionsAPI.createUserAndAssignToRole(getAdminUser().getUsername(), getAdminUser().getPassword(), RM_ADMIN,
getAdminUser().getPassword(),
"Administrator");
STEP("Create record categories and record folders");
Category2 = createRootCategory(getRandomName("recordCategory"));
Folder2 = createFolder(Category2.getId(), getRandomName("recordFolder"));
STEP("Get the unfiled records container");
UnfiledContainer container = getRestAPIFactory().getUnfiledContainersAPI().getUnfiledContainer(UNFILED_RECORDS_CONTAINER_ALIAS);
// Check the response code
assertStatusCode(OK);
//create a rule
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description")
.applyToChildren(true)
.actions(Collections.singletonList(ActionsOnRule.FILE_TO.getActionValue()));
rulesAPI.createRule(getAdminUser().getUsername(), getAdminUser().getPassword(), NODE_PREFIX + container.getId(), ruleDefinition);
//upload an electronic record
UnfiledContainerChild electronicRecord = UnfiledContainerChild.builder()
.name(ELECTRONIC_RECORD_NAME)
.nodeType(CONTENT_TYPE)
.content(RecordContent.builder().mimeType("text/plain").build())
.build();
assertStatusCode(OK);
// create a non-electronic record
UnfiledContainerChild nonelectronicRecord = UnfiledContainerChild.builder()
.properties(UnfiledContainerChildProperties.builder()
.description(NONELECTRONIC_RECORD_NAME)
.title("Title")
.build())
.name(NONELECTRONIC_RECORD_NAME)
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.build();
assertStatusCode(OK);
//delete the record created, delete the rule from UnfilledRecord page, delete the category created
rulesAPI.deleteAllRulesOnContainer(getAdminUser().getUsername(), getAdminUser().getPassword(), NODE_PREFIX + container.getId());
deleteRecordCategory(Category2.getId());
assertStatusCode(NO_CONTENT);
}
}

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-parent</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -1,3 +1,3 @@
SOLR6_TAG=2.0.3
POSTGRES_TAG=13.3
ACTIVEMQ_TAG=5.16.1
POSTGRES_TAG=14.4
ACTIVEMQ_TAG=5.17.1-jre11-rockylinux8

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<properties>
@@ -434,7 +434,7 @@
</run>
</image>
<image>
<name>alfresco/alfresco-activemq:${dependency.activemq.version}</name>
<name>alfresco/alfresco-activemq:${dependency.activemq.version}-jre11-rockylinux8</name>
<run>
<ports>
<port>${activemq.port1}:${activemq.port1}</port>
@@ -505,7 +505,7 @@
</run>
</image>
<image>
<name>alfresco/alfresco-activemq:${dependency.activemq.version}</name>
<name>alfresco/alfresco-activemq:${dependency.activemq.version}-jre11-rockylinux8</name>
<run>
<ports>
<port>${activemq.port1}:${activemq.port1}</port>

View File

@@ -156,25 +156,24 @@ public class ExtendedRuleServiceImpl extends RuleServiceImpl
* @see org.alfresco.repo.rule.RuleServiceImpl#saveRule(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.rule.Rule)
*/
@Override
public void saveRule(final NodeRef nodeRef, final Rule rule)
public Rule saveRule(final NodeRef nodeRef, final Rule rule)
{
validateWormLockRuleAction(rule);
if (filePlanService.isFilePlanComponent(nodeRef))
{
AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
return AuthenticationUtil.runAsSystem(new RunAsWork<Rule>()
{
@Override
public Void doWork()
public Rule doWork()
{
ExtendedRuleServiceImpl.super.saveRule(nodeRef, rule);
return null;
return ExtendedRuleServiceImpl.super.saveRule(nodeRef, rule);
}
});
}
else
{
super.saveRule(nodeRef, rule);
return super.saveRule(nodeRef, rule);
}
}

View File

@@ -82,13 +82,7 @@ public class FilePlanRuleInheritanceTest extends BaseRMTestCase
public void given()
{
filePlan = createFilePlan();
// create a rule that applies to childre
Action completeRecordAction = actionService.createAction(DeclareRecordAction.NAME);
rule = new Rule();
rule.setRuleType("inbound");
rule.setAction(completeRecordAction);
rule.applyToChildren(true);
rule = createRuleThatAppliesToChildren();
}
public void when()
@@ -127,13 +121,7 @@ public class FilePlanRuleInheritanceTest extends BaseRMTestCase
public void given()
{
filePlan = createFilePlan();
// create a rule that applies to childre
Action completeRecordAction = actionService.createAction(DeclareRecordAction.NAME);
rule = new Rule();
rule.setRuleType("inbound");
rule.setAction(completeRecordAction);
rule.applyToChildren(true);
rule = createRuleThatAppliesToChildren();
}
public void when()
@@ -171,13 +159,7 @@ public class FilePlanRuleInheritanceTest extends BaseRMTestCase
public void given()
{
filePlan = createFilePlan();
// create a rule that applies to childre
Action completeRecordAction = actionService.createAction(DeclareRecordAction.NAME);
rule = new Rule();
rule.setRuleType("inbound");
rule.setAction(completeRecordAction);
rule.applyToChildren(true);
rule = createRuleThatAppliesToChildren();
}
public void when()
@@ -215,13 +197,7 @@ public class FilePlanRuleInheritanceTest extends BaseRMTestCase
public void given()
{
filePlan = createFilePlan();
// create a rule that applies to childre
Action completeRecordAction = actionService.createAction(DeclareRecordAction.NAME);
rule = new Rule();
rule.setRuleType("inbound");
rule.setAction(completeRecordAction);
rule.applyToChildren(true);
rule = createRuleThatAppliesToChildren();
}
public void when()
@@ -261,13 +237,7 @@ public class FilePlanRuleInheritanceTest extends BaseRMTestCase
{
filePlan = createFilePlan();
recordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate());
// create a rule that applies to childre
Action completeRecordAction = actionService.createAction(DeclareRecordAction.NAME);
rule = new Rule();
rule.setRuleType("inbound");
rule.setAction(completeRecordAction);
rule.applyToChildren(true);
rule = createRuleThatAppliesToChildren();
}
public void when()
@@ -286,4 +256,15 @@ public class FilePlanRuleInheritanceTest extends BaseRMTestCase
}
});
}
private Rule createRuleThatAppliesToChildren()
{
Action completeRecordAction = actionService.createAction(DeclareRecordAction.NAME);
Rule rule = new Rule();
rule.setRuleType("inbound");
rule.setTitle("Rule name");
rule.setAction(completeRecordAction);
rule.applyToChildren(true);
return rule;
}
}

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<build>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-amps</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2005 - 2020 Alfresco Software Limited.
* Copyright 2005 - 2022 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.
@@ -40,6 +40,7 @@ import org.json.JSONObject;
import org.junit.Assert;
import org.springframework.extensions.webscripts.TestWebScriptServer;
import org.springframework.extensions.webscripts.TestWebScriptServer.GetRequest;
import org.springframework.extensions.webscripts.TestWebScriptServer.Response;
import java.io.Serializable;
import java.util.ArrayList;
@@ -194,13 +195,13 @@ public class SlingshotContentGetTest extends BaseWebScriptTest
NodeRef rootFolder = createNode(companyHome, "rootFolder", ContentModel.TYPE_FOLDER);
NodeRef doc1 = createNodeWithTextContent(rootFolder, "doc1", ContentModel.TYPE_CONTENT, "doc1 file content");
NodeRef doc1 = createNodeWithTextContent(rootFolder, "doc1", ContentModel.TYPE_CONTENT, "doc1 file content", MimetypeMap.MIMETYPE_TEXT_PLAIN);
NodeRef folderX = createNode(rootFolder, "X", ContentModel.TYPE_FOLDER);
NodeRef folderY = createNode(folderX, "Y", ContentModel.TYPE_FOLDER);
NodeRef folderZ = createNode(folderY, "Z", ContentModel.TYPE_FOLDER);
NodeRef doc2 = createNodeWithTextContent(folderZ, "doc2", ContentModel.TYPE_CONTENT, "doc2 file content");
NodeRef doc2 = createNodeWithTextContent(folderZ, "doc2", ContentModel.TYPE_CONTENT, "doc2 file content", MimetypeMap.MIMETYPE_TEXT_PLAIN);
// uri with relative path at the end
String uri = URL_CONTENT_DOWNLOAD + doc1.getId() + "/X/Y/Z/doc2";
@@ -212,7 +213,50 @@ public class SlingshotContentGetTest extends BaseWebScriptTest
nodeService.deleteNode(rootFolder);
}
public NodeRef createNodeWithTextContent(NodeRef parentNode, String nodeCmName, QName nodeType, String content)
public void testForcedAttachment() throws Exception
{
Repository repositoryHelper = (Repository) getServer().getApplicationContext().getBean("repositoryHelper");
NodeRef companyHome = repositoryHelper.getCompanyHome();
NodeRef rootFolder = createNode(companyHome, "rootFolder", ContentModel.TYPE_FOLDER);
NodeRef testhtml = createNodeWithTextContent(rootFolder, "testhtml", ContentModel.TYPE_CONTENT, "testhtml content", MimetypeMap.MIMETYPE_HTML);
NodeRef testpdf = createNodeWithTextContent(rootFolder, "testpdf", ContentModel.TYPE_CONTENT, "testpdf content", MimetypeMap.MIMETYPE_PDF);
String uri = URL_CONTENT_DOWNLOAD + testhtml.getId() + "?a=false";
GetRequest req = new GetRequest(uri);
Response res = sendRequest(req, 200);
assertEquals("attachment", res.getHeader("Content-Disposition"));
assertEquals(MimetypeMap.MIMETYPE_HTML + ";charset=UTF-8", res.getContentType());
uri = URL_CONTENT_DOWNLOAD + testhtml.getId();
res = sendRequest(new GetRequest(uri), 200);
assertEquals("attachment", res.getHeader("Content-Disposition"));
assertEquals(MimetypeMap.MIMETYPE_HTML + ";charset=UTF-8", res.getContentType());
uri = URL_CONTENT_DOWNLOAD + testhtml.getId() + "?a=true";
res = sendRequest(new GetRequest(uri), 200);
assertEquals("attachment", res.getHeader("Content-Disposition"));
assertEquals(MimetypeMap.MIMETYPE_HTML + ";charset=UTF-8", res.getContentType());
uri = URL_CONTENT_DOWNLOAD + testpdf.getId() + "?a=false";
res = sendRequest(new GetRequest(uri), 200);
assertNull(res.getHeader("Content-Disposition"));
assertEquals(MimetypeMap.MIMETYPE_PDF + ";charset=UTF-8", res.getContentType());
uri = URL_CONTENT_DOWNLOAD + testpdf.getId();
res = sendRequest(new GetRequest(uri), 200);
assertNull(res.getHeader("Content-Disposition"));
assertEquals(MimetypeMap.MIMETYPE_PDF + ";charset=UTF-8", res.getContentType());
uri = URL_CONTENT_DOWNLOAD + testpdf.getId() + "?a=true";
res = sendRequest(new GetRequest(uri), 200);
assertEquals("attachment", res.getHeader("Content-Disposition"));
assertEquals(MimetypeMap.MIMETYPE_PDF + ";charset=UTF-8", res.getContentType());
nodeService.deleteNode(rootFolder);
}
public NodeRef createNodeWithTextContent(NodeRef parentNode, String nodeCmName, QName nodeType, String content, String mimetype)
{
NodeRef nodeRef = createNode(parentNode, nodeCmName, nodeType);
@@ -220,7 +264,7 @@ public class SlingshotContentGetTest extends BaseWebScriptTest
if (content != null)
{
ContentWriter writer = contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
writer.setMimetype(mimetype);
writer.setEncoding("UTF-8");
writer.putContent(content);
}

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<dependencies>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<dependencies>

View File

@@ -9,6 +9,6 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
</project>

View File

@@ -1,6 +1,6 @@
# Fetch image based on Tomcat 9.0, Java 11 and Centos 7
# Fetch image based on Tomcat 9.0, Java 17 and Rocky Linux 8
# More infos about this image: https://github.com/Alfresco/alfresco-docker-base-tomcat
FROM alfresco/alfresco-base-tomcat:tomcat9-jre11-centos7-202203091924
FROM alfresco/alfresco-base-tomcat:tomcat9-jre17-rockylinux8-202205140719
# Set default docker_context.
ARG resource_path=target
@@ -65,12 +65,12 @@ RUN sed -i -e "s_log4j.appender.File.File\=alfresco.log_log4j.appender.File.File
# fontconfig is required by Activiti worflow diagram generator
# installing pinned dependencies as well
RUN yum install -y fontconfig-2.13.0-4.3.el7 \
dejavu-fonts-common-2.33-6.el7 \
fontpackages-filesystem-1.44-8.el7 \
freetype-2.8-14.el7_9.1 \
libpng-1.5.13-8.el7 \
dejavu-sans-fonts-2.33-6.el7 && \
RUN yum install -y fontconfig-2.13.1-4.el8 \
dejavu-fonts-common-2.35-7.el8 \
fontpackages-filesystem-1.44-22.el8 \
freetype-2.9.1-4.el8_3.1 \
libpng-1.6.34-5.el8 \
dejavu-sans-fonts-2.35-7.el8 && \
yum clean all
# The standard configuration is to have all Tomcat files owned by root with group GROUPNAME and whilst owner has read/write privileges,

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -1,3 +1,3 @@
SOLR6_TAG=2.0.3
POSTGRES_TAG=13.3
ACTIVEMQ_TAG=5.16.1
POSTGRES_TAG=14.4
ACTIVEMQ_TAG=5.17.1-jre11-rockylinux8

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<developers>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<developers>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<developers>
@@ -106,8 +106,10 @@
<suiteXmlFiles>
<suiteXmlFile>${suiteXmlFile}</suiteXmlFile>
</suiteXmlFiles>
<!-- Keeping illegal-access=warn for Java 11 compatibility, even though it has no effect on JDK 17 -->
<argLine>
--illegal-access=warn
--add-opens=java.base/java.lang=ALL-UNNAMED
</argLine>
</configuration>
</plugin>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<developers>
@@ -78,8 +78,10 @@
<suiteXmlFiles>
<suiteXmlFile>${suiteXmlFile}</suiteXmlFile>
</suiteXmlFiles>
<!-- Keeping illegal-access=warn for Java 11 compatibility, even though it has no effect on JDK 17 -->
<argLine>
--illegal-access=warn
--add-opens=java.base/java.lang=ALL-UNNAMED
</argLine>
</configuration>
</plugin>

View File

@@ -0,0 +1,395 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2022 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.rules;
import static java.util.stream.Collectors.toList;
import static org.alfresco.rest.rules.RulesTestsUtils.*;
import static org.alfresco.utility.constants.UserRole.SiteCollaborator;
import static org.alfresco.utility.constants.UserRole.SiteConsumer;
import static org.alfresco.utility.constants.UserRole.SiteContributor;
import static org.alfresco.utility.constants.UserRole.SiteManager;
import static org.alfresco.utility.model.FileModel.getRandomFileModel;
import static org.alfresco.utility.model.FileType.TEXT_PLAIN;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.junit.Assert.assertEquals;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;
import org.alfresco.rest.RestTest;
import org.alfresco.rest.model.RestActionBodyExecTemplateModel;
import org.alfresco.rest.model.RestRuleModel;
import org.alfresco.rest.model.RestRuleModelsCollection;
import org.alfresco.utility.constants.UserRole;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.SiteModel;
import org.alfresco.utility.model.TestGroup;
import org.alfresco.utility.model.UserModel;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* Tests for POST /nodes/{nodeId}/rule-sets/{ruleSetId}/rules.
*/
@Test(groups = {TestGroup.RULES})
public class CreateRulesTests extends RestTest
{
private static final String IGNORE_ID = "id";
private static final String IGNORE_IS_SHARED = "isShared";
private UserModel user;
private SiteModel site;
private FolderModel ruleFolder;
@BeforeClass(alwaysRun = true)
public void dataPreparation()
{
user = dataUser.createRandomTestUser();
site = dataSite.usingUser(user).createPublicRandomSite();
ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder();
}
/**
* Check we can create a rule.
* <p>
* Also check that the isShared field is not returned when not requested.
*/
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void createRule()
{
RestRuleModel ruleModel = createRuleModelWithModifiedValues();
RestRuleModel rule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.createSingleRule(ruleModel);
RestRuleModel expectedRuleModel = createRuleModelWithModifiedValues();
expectedRuleModel.setActions(addActionContextParams(expectedRuleModel.getActions()));
expectedRuleModel.setConditions(createEmptyConditionModel());
restClient.assertStatusCodeIs(CREATED);
rule.assertThat().isEqualTo(expectedRuleModel, IGNORE_ID, IGNORE_IS_SHARED)
.assertThat().field("id").isNotNull()
.assertThat().field("isShared").isNull();
}
/** Check creating a rule in a non-existent folder returns an error. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void createRuleInNonExistentFolder()
{
STEP("Try to create a rule in non-existent folder.");
FolderModel nonExistentFolder = FolderModel.getRandomFolderModel();
nonExistentFolder.setNodeRef("fake-id");
RestRuleModel ruleModel = new RestRuleModel();
ruleModel.setName("ruleName");
restClient.authenticateUser(user).withCoreAPI().usingNode(nonExistentFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
restClient.assertStatusCodeIs(NOT_FOUND);
restClient.assertLastError().containsSummary("fake-id was not found");
}
/** Check creating a rule in a non-existent rule set returns an error. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void createRuleInNonExistentRuleSet()
{
STEP("Try to create a rule in non-existent rule set.");
RestRuleModel ruleModel = new RestRuleModel();
ruleModel.setName("ruleName");
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingRuleSet("fake-id").createSingleRule(ruleModel);
restClient.assertStatusCodeIs(NOT_FOUND);
restClient.assertLastError().containsSummary("fake-id was not found");
}
/** Try to create a rule without a name and check the error. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void createRuleWithEmptyName()
{
RestRuleModel ruleModel = createRuleModel("");
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
restClient.assertStatusCodeIs(BAD_REQUEST);
restClient.assertLastError().containsSummary("Rule name is a mandatory parameter");
}
/** Check we can create two rules with the same name. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void duplicateRuleNameIsAcceptable()
{
RestRuleModel ruleModel = createRuleModel("duplicateRuleName");
STEP("Create two identical rules");
RestRuleModel ruleA = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
RestRuleModel ruleB = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
// Check that the names are the same but the ids are different.
ruleA.assertThat().field("name").is(ruleB.getName());
ruleA.assertThat().field("id").isNot(ruleB.getId());
}
/** Check that a user without permission to view the folder cannot create a rule in it. */
public void requireReadPermissionToCreateRule()
{
STEP("Create a user and use them to create a private site containing a folder");
UserModel privateUser = dataUser.createRandomTestUser();
SiteModel privateSite = dataSite.usingUser(privateUser).createPrivateRandomSite();
FolderModel privateFolder = dataContent.usingUser(privateUser).usingSite(privateSite).createFolder();
STEP("Try to use a different user to create a rule in the private folder");
RestRuleModel ruleModel = new RestRuleModel();
ruleModel.setName("ruleName");
restClient.authenticateUser(user).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
restClient.assertStatusCodeIs(FORBIDDEN);
restClient.assertLastError().containsSummary("Insufficient permissions to manage rules");
}
/** Check that a Collaborator cannot create a rule in a private folder. */
public void siteCollaboratorCannotCreateRule()
{
testRolePermissionsWith(SiteCollaborator);
restClient.assertStatusCodeIs(FORBIDDEN);
restClient.assertLastError().containsSummary("Insufficient permissions to manage rules");
}
/** Check that a Contributor cannot create a rule in a private folder. */
public void siteContributorCannotCreateRule()
{
testRolePermissionsWith(SiteContributor);
restClient.assertStatusCodeIs(FORBIDDEN);
restClient.assertLastError().containsSummary("Insufficient permissions to manage rules");
}
/** Check that a Consumer cannot create a rule in a private folder. */
public void siteConsumerCannotCreateRule()
{
testRolePermissionsWith(SiteConsumer);
restClient.assertStatusCodeIs(FORBIDDEN);
restClient.assertLastError().containsSummary("Insufficient permissions to manage rules");
}
/** Check that a siteManager can create a rule in a private folder. */
public void siteManagerCanCreateRule()
{
testRolePermissionsWith(SiteManager)
.assertThat().field("id").isNotNull()
.assertThat().field("name").is("testRule");
restClient.assertStatusCodeIs(CREATED);
}
/** Check we can't create a rule under a document node. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void tryToCreateRuleUnderDocument()
{
STEP("Create a document.");
FileModel fileModel = dataContent.usingUser(user).usingSite(site).createContent(getRandomFileModel(TEXT_PLAIN));
RestRuleModel ruleModel = new RestRuleModel();
ruleModel.setName("ruleName");
restClient.authenticateUser(user).withCoreAPI().usingNode(fileModel).usingDefaultRuleSet().createSingleRule(ruleModel);
restClient.assertStatusCodeIs(BAD_REQUEST);
restClient.assertLastError().containsSummary("folder is expected");
}
/** Check we can create several rules. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void createRules()
{
STEP("Create a list of rules in one POST request");
List<String> ruleNames = List.of("ruleA", "ruleB", "ruleC");
List<RestRuleModel> ruleModels = ruleNames.stream().map(RulesTestsUtils::createRuleModel).collect(toList());
RestRuleModelsCollection rules = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.createListOfRules(ruleModels);
restClient.assertStatusCodeIs(CREATED);
assertEquals("Unexpected number of rules received in response.", ruleNames.size(), rules.getEntries().size());
IntStream.range(0, ruleModels.size()).forEach(i ->
rules.getEntries().get(i).onModel()
.assertThat().field("id").isNotNull()
.assertThat().field("name").is(ruleNames.get(i)));
}
/** Try to create several rules with an error in one of them. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void createRulesWithOneError()
{
STEP("Try to create a three rules but the middle one has an error.");
RestRuleModel ruleA = createRuleModel("ruleA");
RestRuleModel ruleB = createRuleModel("");
// Don't set a name for Rule B.
RestRuleModel ruleC = createRuleModel("ruleC");
List<RestRuleModel> ruleModels = List.of(ruleA, ruleB, ruleC);
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().createListOfRules(ruleModels);
restClient.assertStatusCodeIs(BAD_REQUEST);
restClient.assertLastError().containsSummary("Rule name is a mandatory parameter");
}
/** Check we can create a rule without description. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void createRuleWithoutDescription()
{
RestRuleModel ruleModel = createRuleModelWithDefaultValues();
UserModel admin = dataUser.getAdminUser();
RestRuleModel rule = restClient.authenticateUser(admin).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.createSingleRule(ruleModel);
restClient.assertStatusCodeIs(CREATED);
rule.assertThat().field("id").isNotNull()
.assertThat().field("name").is(RULE_NAME_DEFAULT)
.assertThat().field("description").isNull();
}
/** Check we can create a rule without specifying triggers but with the default "inbound" value. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void createRuleWithoutTriggers()
{
RestRuleModel ruleModel = createRuleModelWithDefaultValues();
UserModel admin = dataUser.getAdminUser();
RestRuleModel rule = restClient.authenticateUser(admin).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.createSingleRule(ruleModel);
restClient.assertStatusCodeIs(CREATED);
rule.assertThat().field("id").isNotNull()
.assertThat().field("name").is(RULE_NAME_DEFAULT)
.assertThat().field("triggers").is(List.of("inbound"));
}
/** Check we can create a rule without error script. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void createRuleWithoutErrorScript()
{
RestRuleModel ruleModel = createRuleModelWithDefaultValues();
UserModel admin = dataUser.getAdminUser();
RestRuleModel rule = restClient.authenticateUser(admin).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.createSingleRule(ruleModel);
restClient.assertStatusCodeIs(CREATED);
rule.assertThat().field("id").isNotNull()
.assertThat().field("name").is(RULE_NAME_DEFAULT)
.assertThat().field("errorScript").isNull();
}
/** Check we can create a rule with irrelevant isShared flag, and it doesn't have impact to the process. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void createRuleWithSharedFlag()
{
RestRuleModel ruleModel = createRuleModelWithDefaultValues();
ruleModel.setIsShared(true);
UserModel admin = dataUser.getAdminUser();
RestRuleModel rule = restClient.authenticateUser(admin).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.createSingleRule(ruleModel);
restClient.assertStatusCodeIs(CREATED);
rule.assertThat().field("id").isNotNull()
.assertThat().field("name").is(RULE_NAME_DEFAULT)
.assertThat().field("isShared").isNull();
}
/** Check we can create a rule. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void createRuleAndIncludeFieldsInResponse()
{
RestRuleModel ruleModel = createRuleModel("ruleName");
RestRuleModel rule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.include("isShared")
.createSingleRule(ruleModel);
restClient.assertStatusCodeIs(CREATED);
rule.assertThat().field("isShared").isNotNull();
}
public RestRuleModel testRolePermissionsWith(UserRole userRole)
{
STEP("Create a user and use them to create a private site containing a folder");
SiteModel privateSite = dataSite.usingUser(user).createPrivateRandomSite();
FolderModel privateFolder = dataContent.usingUser(user).usingSite(privateSite).createFolder();
STEP(String.format("Add a user with '%s' role in the private site's folder", userRole.toString()));
UserModel userWithRole = dataUser.createRandomTestUser();
dataUser.addUserToSite(userWithRole, privateSite, userRole);
RestRuleModel ruleModel = createRuleModel("testRule", List.of(createDefaultActionModel()));
return restClient.authenticateUser(userWithRole).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
}
/**
* Check we can create a rule with several actions.
*/
@Test(groups = {TestGroup.REST_API, TestGroup.RULES})
public void createRuleWithActions()
{
final Map<String, Serializable> copyParams =
Map.of("destination-folder", "dummy-folder-node", "deep-copy", true);
final RestActionBodyExecTemplateModel copyAction = createCustomActionModel("copy", copyParams);
final Map<String, Serializable> checkOutParams =
Map.of("destination-folder", "dummy-folder-node", "assoc-name", "cm:checkout", "assoc-type",
"cm:contains");
final RestActionBodyExecTemplateModel checkOutAction = createCustomActionModel("check-out", checkOutParams);
final Map<String, Serializable> scriptParams = Map.of("script-ref", "dummy-script-node-id");
final RestActionBodyExecTemplateModel scriptAction = createCustomActionModel("script", scriptParams);
final RestRuleModel ruleModel = createRuleModelWithDefaultValues();
ruleModel.setActions(Arrays.asList(copyAction, checkOutAction, scriptAction));
final UserModel admin = dataUser.getAdminUser();
final RestRuleModel rule = restClient.authenticateUser(admin).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.createSingleRule(ruleModel);
final RestRuleModel expectedRuleModel = createRuleModelWithDefaultValues();
expectedRuleModel.setActions(addActionContextParams(Arrays.asList(copyAction, checkOutAction, scriptAction)));
expectedRuleModel.setConditions(createEmptyConditionModel());
expectedRuleModel.setTriggers(List.of("inbound"));
restClient.assertStatusCodeIs(CREATED);
rule.assertThat().isEqualTo(expectedRuleModel, IGNORE_ID, IGNORE_IS_SHARED)
.assertThat().field("isShared").isNull();
}
}

View File

@@ -0,0 +1,254 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2022 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.rules;
import static java.util.stream.Collectors.toList;
import static org.alfresco.rest.rules.RulesTestsUtils.createRuleModel;
import static org.alfresco.utility.constants.UserRole.SiteCollaborator;
import static org.alfresco.utility.constants.UserRole.SiteContributor;
import static org.alfresco.utility.constants.UserRole.SiteManager;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import static org.springframework.http.HttpStatus.NO_CONTENT;
import static org.springframework.http.HttpStatus.OK;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.alfresco.rest.RestTest;
import org.alfresco.rest.model.RestRuleModel;
import org.alfresco.rest.model.RestRuleModelsCollection;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.SiteModel;
import org.alfresco.utility.model.TestGroup;
import org.alfresco.utility.model.UserModel;
import org.junit.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* Tests for DELETE /nodes/{nodeId}/rule-sets/{ruleSetId}/rules/{ruleId}.
*/
@Test(groups = {TestGroup.RULES})
public class DeleteRulesTests extends RestTest
{
private static final String FAKE_NODE_REF = "fake-node-id";
private UserModel user;
private SiteModel site;
@BeforeClass(alwaysRun = true)
public void dataPreparation()
{
STEP("Create a Contributor user and a public site");
user = dataUser.createRandomTestUser();
user.setUserRole(SiteContributor);
site = dataSite.usingUser(user).createPublicRandomSite();
}
/**
* Delete previously created rule by its id (as Contributor).
*/
@Test(groups = {TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY})
public void deleteSingleRuleAndGet204()
{
STEP("Create a few rules in the folder");
final FolderModel ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder();
final List<RestRuleModel> createdRules = Stream.of("ruleA", "ruleB", "ruleC")
.map(ruleName -> {
RestRuleModel ruleModel = createRuleModel(ruleName);
return restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.createSingleRule(ruleModel);
})
.collect(toList());
STEP("Attempt delete one rule");
final RestRuleModel ruleA = createdRules.get(0);
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().deleteRule(ruleA.getId());
restClient.assertStatusCodeIs(NO_CONTENT);
STEP("Get and check the rules from the folder after deleting one of them");
final RestRuleModelsCollection rulesAfterDeletion =
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().getListOfRules();
restClient.assertStatusCodeIs(OK);
rulesAfterDeletion.assertThat().entriesListCountIs(createdRules.size() - 1);
Assert.assertTrue(rulesAfterDeletion.getEntries()
.stream()
.noneMatch(r -> r.onModel().getId().equals(ruleA.getId()))
);
final Set<String> ruleIdsThatShouldBeLeft = createdRules.stream()
.filter(r -> !r.getName().equals("ruleA"))
.map(RestRuleModel::getId)
.collect(Collectors.toSet());
final Set<String> ruleIdsAfterDeletion = rulesAfterDeletion.getEntries().stream()
.map(r -> r.onModel().getId())
.collect(Collectors.toSet());
Assert.assertEquals(ruleIdsThatShouldBeLeft, ruleIdsAfterDeletion);
}
/**
* Try to delete a rule in a non-existing folder and get 404.
*/
@Test(groups = {TestGroup.REST_API, TestGroup.RULES})
public void deleteRuleInNonExistingFolderAndGet404()
{
final FolderModel ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder();
final RestRuleModel testRule = createRule(ruleFolder);
STEP("Create a non-existing folder model");
final FolderModel nonExistingFolder = new FolderModel();
nonExistingFolder.setNodeRef(FAKE_NODE_REF);
STEP("Attempt delete the rule in non-existing folder");
restClient.authenticateUser(user).withCoreAPI().usingNode(nonExistingFolder).usingDefaultRuleSet().deleteRule(testRule.getId());
restClient.assertLastError().statusCodeIs(NOT_FOUND);
}
/**
* Try to delete a rule in a non-existing rule set and get 404.
*/
@Test(groups = {TestGroup.REST_API, TestGroup.RULES})
public void deleteRuleInNonExistingRuleSetAndGet404()
{
final FolderModel ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder();
final RestRuleModel testRule = createRule(ruleFolder);
STEP("Attempt delete the rule in non-existing rule set");
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingRuleSet(FAKE_NODE_REF).deleteRule(testRule.getId());
restClient.assertLastError().statusCodeIs(NOT_FOUND);
}
/**
* Try to delete a non-existing rule and get 404.
*/
@Test(groups = {TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY})
public void deleteNonExistingRuleAndGet404()
{
final FolderModel ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder();
STEP("Attempt delete non-existing rule");
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().deleteRule(FAKE_NODE_REF);
restClient.assertLastError().statusCodeIs(NOT_FOUND);
}
/**
* Try to delete an existing rule passing a wrong but existing folder and get 404.
*/
@Test(groups = {TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY})
public void deleteExistingRuleFromWrongFolderAndGet404()
{
final FolderModel ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder();
final RestRuleModel testRule = createRule(ruleFolder);
STEP("Create a second folder in the site");
final FolderModel anotherFolder = dataContent.usingUser(user).usingSite(site).createFolder();
STEP("Attempt delete an existing rule from a wrong but existing (second) folder");
restClient.authenticateUser(user).withCoreAPI().usingNode(anotherFolder).usingDefaultRuleSet().deleteRule(testRule.getId());
restClient.assertLastError().statusCodeIs(NOT_FOUND);
}
/**
* Check that a user without write permission on folder cannot delete a rule inside it.
*/
public void deleteSinglePrivateRuleWithoutPermissionAndGet403()
{
STEP("Create a user and use them to create a private site containing a folder with a rule");
final UserModel privateUser = dataUser.createRandomTestUser();
final SiteModel privateSite = dataSite.usingUser(privateUser).createPrivateRandomSite();
final FolderModel privateFolder = dataContent.usingUser(privateUser).usingSite(privateSite).createFolder();
final RestRuleModel ruleModel = createRuleModel("Private site rule");
final RestRuleModel createdRule =
restClient.authenticateUser(privateUser).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet()
.createSingleRule(ruleModel);
STEP("Try to delete the rule with another user");
restClient.authenticateUser(user).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet().deleteRule(createdRule.getId());
restClient.assertLastError().statusCodeIs(FORBIDDEN);
}
/**
* Check that a user with SiteCollaborator permissions on folder can delete a rule inside it.
*/
public void deleteSinglePublicRuleAsCollaboratorAndGet403()
{
STEP("Create a user and use them to create a private site containing a folder with a rule");
final FolderModel ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder();
final RestRuleModel testRule = createRule(ruleFolder);
STEP("Create a manager in the private site");
final UserModel siteCollaborator = dataUser.createRandomTestUser();
siteCollaborator.setUserRole(SiteCollaborator);
restClient.authenticateUser(user).withCoreAPI().usingSite(site).addPerson(siteCollaborator);
STEP("Check the manager can delete the rule");
restClient.authenticateUser(siteCollaborator).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.deleteRule(testRule.getId());
restClient.assertLastError().statusCodeIs(FORBIDDEN);
}
/**
* Check that a user with SiteManager permissions on folder can delete a rule inside it.
*/
public void deleteSinglePrivateRuleAsSiteManagerAndGet204()
{
STEP("Create a user and use them to create a private site containing a folder with a rule");
final UserModel privateUser = dataUser.createRandomTestUser();
final SiteModel privateSite = dataSite.usingUser(privateUser).createPrivateRandomSite();
final FolderModel privateFolder = dataContent.usingUser(privateUser).usingSite(privateSite).createFolder();
final RestRuleModel ruleModel = createRuleModel("Private site rule");
final RestRuleModel createdRule =
restClient.authenticateUser(privateUser).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet()
.createSingleRule(ruleModel);
STEP("Create a manager in the private site");
final UserModel siteManager = dataUser.createRandomTestUser();
siteManager.setUserRole(SiteManager);
restClient.authenticateUser(privateUser).withCoreAPI().usingSite(privateSite).addPerson(siteManager);
STEP("Check the manager can delete the rule");
restClient.authenticateUser(siteManager).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet()
.deleteRule(createdRule.getId());
restClient.assertStatusCodeIs(NO_CONTENT);
}
private RestRuleModel createRule(FolderModel ruleFolder)
{
STEP("Create a rule in the folder");
final RestRuleModel ruleModel = createRuleModel("Test rule");
return restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
}
}

View File

@@ -0,0 +1,210 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2022 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.rules;
import static org.alfresco.rest.rules.RulesTestsUtils.createRuleModel;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.junit.Assert.assertTrue;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import static org.springframework.http.HttpStatus.OK;
import org.alfresco.rest.RestTest;
import org.alfresco.rest.model.RestRuleModel;
import org.alfresco.rest.model.RestRuleSetModel;
import org.alfresco.rest.model.RestRuleSetModelsCollection;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.SiteModel;
import org.alfresco.utility.model.TestGroup;
import org.alfresco.utility.model.UserModel;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* Tests for GET /nodes/{nodeId}/rule-sets and /nodes/{nodeId}/rule-sets/{ruleSetId}.
*/
@Test (groups = { TestGroup.RULES })
public class GetRuleSetsTests extends RestTest
{
private UserModel user;
private SiteModel site;
private FolderModel ruleFolder;
private RestRuleModel rule;
private String ruleSetId;
@BeforeClass (alwaysRun = true)
public void dataPreparation()
{
STEP("Create a user, site and folder.");
user = dataUser.createRandomTestUser();
site = dataSite.usingUser(user).createPublicRandomSite();
ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder();
STEP("Create a rule in the folder.");
RestRuleModel ruleModel = createRuleModel("ruleName");
rule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.createSingleRule(ruleModel);
STEP("Get the rule sets for the folder and find the rule set id");
RestRuleSetModelsCollection ruleSets = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder)
.getListOfRuleSets();
ruleSets.assertThat().entriesListCountIs(1);
ruleSetId = ruleSets.getEntries().get(0).onModel().getId();
}
/** Check we can get an empty list of rule sets. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void getEmptyRuleSetsList()
{
STEP("Create a folder in existing site");
FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder();
STEP("Get the rule sets for the folder");
RestRuleSetModelsCollection ruleSets = restClient.authenticateUser(user).withCoreAPI()
.usingNode(folder).getListOfRuleSets();
restClient.assertStatusCodeIs(OK);
assertTrue("Expected no rule sets to be present.", ruleSets.isEmpty());
}
/** Check we can get a list of rule sets. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void getRuleSetsList()
{
STEP("Get the rule sets for the folder");
RestRuleSetModelsCollection ruleSets = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder)
.getListOfRuleSets();
restClient.assertStatusCodeIs(OK);
ruleSets.assertThat().entriesListCountIs(1);
ruleSets.getEntries().get(0).onModel()
.assertThat().field("id").isNotNull();
}
/** Check we get a 404 if trying to load rule sets for a folder that doesn't exist. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void getRuleSetsForNonExistentFolder()
{
STEP("Try to load rule sets for a non-existent folder.");
FolderModel nonExistentFolder = FolderModel.getRandomFolderModel();
nonExistentFolder.setNodeRef("fake-id");
restClient.authenticateUser(user).withCoreAPI().usingNode(nonExistentFolder).getListOfRuleSets();
restClient.assertStatusCodeIs(NOT_FOUND);
}
/** Check we can get the id of the folder that owns a list of rule sets. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void getRuleSetsAndOwningFolders()
{
STEP("Get the rule sets and owning folders");
RestRuleSetModelsCollection ruleSets = restClient.authenticateUser(user).withCoreAPI()
.usingNode(ruleFolder)
.include("owningFolder")
.getListOfRuleSets();
restClient.assertStatusCodeIs(OK);
ruleSets.getEntries().get(0).onModel()
.assertThat().field("owningFolder").is(ruleFolder.getNodeRef())
.assertThat().field("id").is(ruleSetId);
ruleSets.assertThat().entriesListCountIs(1);
}
/** Check we can get the reason that a rule set is included in the list. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void getRuleSetsAndInclusionType()
{
STEP("Get the rule sets and inclusion type");
RestRuleSetModelsCollection ruleSets = restClient.authenticateUser(user).withCoreAPI()
.usingNode(ruleFolder)
.include("inclusionType")
.getListOfRuleSets();
restClient.assertStatusCodeIs(OK);
ruleSets.getEntries().get(0).onModel()
.assertThat().field("inclusionType").is("owned")
.assertThat().field("id").is(ruleSetId);
ruleSets.assertThat().entriesListCountIs(1);
}
/** Check we can get a rule set by its id. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void getRuleSetById()
{
STEP("Get the rule set using its rule set id");
RestRuleSetModel ruleSet = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder)
.getRuleSet(ruleSetId);
restClient.assertStatusCodeIs(OK);
ruleSet.assertThat().field("id").is(ruleSetId);
}
/** Check we can get a rule set using the "-default-" synonym. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void getDefaultRuleSetById()
{
STEP("Get the default rule set for the folder");
RestRuleSetModel ruleSet = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder)
.getDefaultRuleSet();
restClient.assertStatusCodeIs(OK);
ruleSet.assertThat().field("id").isNotNull();
}
/** Check we get a 404 if trying to load the default rule set for a folder that doesn't exist. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void getDefaultRuleSetForNonExistentFolder()
{
STEP("Try to load a rule set for a non-existent folder.");
FolderModel nonExistentFolder = FolderModel.getRandomFolderModel();
nonExistentFolder.setNodeRef("fake-id");
restClient.authenticateUser(user).withCoreAPI().usingNode(nonExistentFolder).getDefaultRuleSet();
restClient.assertStatusCodeIs(NOT_FOUND);
}
/** Check we get 404 for a non-existing rule set id. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void getRuleSetByNonExistingId()
{
STEP("Get the rule set using fake rule set id");
String fakeRuleSetId = "fake-rule-set-id";
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).getRuleSet(fakeRuleSetId);
restClient.assertStatusCodeIs(NOT_FOUND);
}
/** Check we can get the id of the folder that owns a rule set. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void getRuleSetAndOwningFolder()
{
STEP("Get the rule set and owning folder");
RestRuleSetModel ruleSet = restClient.authenticateUser(user).withCoreAPI()
.usingNode(ruleFolder)
.include("owningFolder")
.getRuleSet(ruleSetId);
restClient.assertStatusCodeIs(OK);
ruleSet.assertThat().field("owningFolder").is(ruleFolder.getNodeRef())
.assertThat().field("id").is(ruleSetId);
}
}

View File

@@ -0,0 +1,312 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rules;
import static java.util.stream.Collectors.toList;
import static org.alfresco.rest.rules.RulesTestsUtils.*;
import static org.alfresco.utility.constants.UserRole.SiteCollaborator;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.junit.Assert.assertTrue;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import static org.springframework.http.HttpStatus.OK;
import static org.springframework.http.HttpStatus.CREATED;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import org.alfresco.rest.RestTest;
import org.alfresco.rest.model.RestRuleModel;
import org.alfresco.rest.model.RestRuleModelsCollection;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.SiteModel;
import org.alfresco.utility.model.TestGroup;
import org.alfresco.utility.model.UserModel;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* Tests for GET /nodes/{nodeId}/rule-sets/{ruleSetId}/rules and GET /nodes/{nodeId}/rule-sets/{ruleSetId}/rules/{ruleId}.
*/
@Test(groups = {TestGroup.RULES})
public class GetRulesTests extends RestTest
{
private UserModel user;
private SiteModel site;
private FolderModel ruleFolder;
private List<RestRuleModel> createdRules;
private RestRuleModel createdRuleA;
private static final String IGNORE_ID = "id";
private static final String IGNORE_IS_SHARED = "isShared";
@BeforeClass(alwaysRun = true)
public void dataPreparation()
{
STEP("Create a user, site and folder");
user = dataUser.createRandomTestUser();
site = dataSite.usingUser(user).createPublicRandomSite();
ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder();
STEP("Create rules in the folder");
createdRules = Stream.of("ruleA", "ruleB").map(ruleName -> {
RestRuleModel ruleModel = createRuleModel(ruleName);
return restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
}).collect(toList());
createdRuleA = createdRules.get(0);
}
/** Check we can get an empty list of rules. */
@Test(groups = { TestGroup.REST_API, TestGroup.RULES })
public void getEmptyRulesList()
{
STEP("Create a folder in existing site");
FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder();
STEP("Get the rules that apply to the folder");
RestRuleModelsCollection rules = restClient.authenticateUser(user).withCoreAPI().usingNode(folder).usingDefaultRuleSet().getListOfRules();
restClient.assertStatusCodeIs(NOT_FOUND);
assertTrue("Expected no rules to be present.", rules.isEmpty());
}
/**
* Check we can get all the rules for a folder.
* <p>
* Also check that the isShared field is not returned when not requested.
*/
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void getRulesList()
{
STEP("Get the rules that apply to the folder");
RestRuleModelsCollection rules = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().getListOfRules();
restClient.assertStatusCodeIs(OK);
rules.assertThat().entriesListCountIs(createdRules.size());
IntStream.range(0, createdRules.size()).forEach(i ->
rules.getEntries().get(i).onModel()
.assertThat().field("id").is(createdRules.get(i).getId())
.assertThat().field("name").is(createdRules.get(i).getName())
.assertThat().field("isShared").isNull());
}
/** Check we get a 404 if trying to load rules for a folder that doesn't exist. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void getRulesForNonExistentFolder()
{
STEP("Try to load rules for a non-existent folder.");
FolderModel nonExistentFolder = FolderModel.getRandomFolderModel();
nonExistentFolder.setNodeRef("fake-id");
restClient.authenticateUser(user).withCoreAPI().usingNode(nonExistentFolder).usingDefaultRuleSet().getListOfRules();
restClient.assertStatusCodeIs(NOT_FOUND);
}
/** Check we get a 404 if trying to load rules with a rule set id that doesn't exist. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void getRulesFromNonExistentRuleSet()
{
STEP("Create a folder in existing site");
FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder();
STEP("Try to load rules for a non-existent rule set.");
restClient.authenticateUser(user).withCoreAPI().usingNode(folder).usingRuleSet("fake-id").getListOfRules();
restClient.assertStatusCodeIs(NOT_FOUND);
}
/** Check we can get all the rules for a folder along with the extra "include" and "other" fields. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void getRulesListWithIncludedFields()
{
STEP("Get the rules that apply to the folder");
RestRuleModelsCollection rules = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.include("isShared")
.getListOfRules();
rules.assertThat().entriesListCountIs(createdRules.size());
IntStream.range(0, createdRules.size()).forEach(i ->
rules.getEntries().get(i).onModel()
.assertThat().field("isShared").isNotNull()
.assertThat().field("description").isNull()
.assertThat().field("enabled").is(false)
.assertThat().field("cascade").is(false)
.assertThat().field("asynchronous").is(false)
.assertThat().field("errorScript").isNull()
.assertThat().field("shared").isNull()
.assertThat().field("triggers").is("[inbound]"));
}
/**
* Check we can get a rule by its id.
* <p>
* Also check that the isShared field is not returned when not requested.
*/
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void getSingleRule()
{
STEP("Load a particular rule");
RestRuleModel rule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().getSingleRule(createdRuleA.getId());
restClient.assertStatusCodeIs(OK);
rule.assertThat().field("id").is(createdRuleA.getId())
.assertThat().field("name").is(createdRuleA.getName())
.assertThat().field("isShared").isNull();
}
/** Check we can get rule's other fields */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void getRulesOtherFieldsModified()
{
STEP("Create a rule with all other fields default values modified");
RestRuleModel ruleModel = createRuleModelWithModifiedValues();
ruleModel.setTriggers(List.of("update"));
UserModel admin = dataUser.getAdminUser();
FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder();
RestRuleModel rule = restClient.authenticateUser(admin).withCoreAPI().usingNode(folder).usingDefaultRuleSet()
.createSingleRule(ruleModel);
RestRuleModel expectedRuleModel = createRuleModelWithModifiedValues();
expectedRuleModel.setActions(addActionContextParams(expectedRuleModel.getActions()));
expectedRuleModel.setTriggers(List.of("update"));
expectedRuleModel.setConditions(createEmptyConditionModel());
restClient.assertStatusCodeIs(CREATED);
rule.assertThat().isEqualTo(expectedRuleModel, IGNORE_ID, IGNORE_IS_SHARED)
.assertThat().field("id").isNotNull()
.assertThat().field("isShared").isNull();
}
/** Check we can get rule's "other" fields */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void getRulesDefaultFields()
{
STEP("Create a rule with all other fields default values");
RestRuleModel ruleModel = createRuleModelWithDefaultValues();
UserModel admin = dataUser.getAdminUser();
FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder();
RestRuleModel rule = restClient.authenticateUser(admin).withCoreAPI().usingNode(folder).usingDefaultRuleSet()
.createSingleRule(ruleModel);
RestRuleModel expectedRuleModel = createRuleModelWithDefaultValues();
expectedRuleModel.setActions(addActionContextParams(expectedRuleModel.getActions()));
expectedRuleModel.setTriggers(List.of("inbound"));
expectedRuleModel.setConditions(createEmptyConditionModel());
restClient.assertStatusCodeIs(CREATED);
restClient.assertStatusCodeIs(CREATED);
rule.assertThat().isEqualTo(expectedRuleModel, IGNORE_ID, IGNORE_IS_SHARED)
.assertThat().field("id").isNotNull()
.assertThat().field("isShared").isNull();
}
/** Check we get a 404 if trying to load a rule from a folder that doesn't exist. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void getSingleRuleFromNonExistentFolder()
{
STEP("Try to load a rule from a non-existent folder.");
FolderModel nonExistentFolder = FolderModel.getRandomFolderModel();
nonExistentFolder.setNodeRef("fake-id");
restClient.authenticateUser(user).withCoreAPI().usingNode(nonExistentFolder).usingDefaultRuleSet().getSingleRule("fake-rule-id");
restClient.assertStatusCodeIs(NOT_FOUND);
}
/** Check we get a 404 if trying to load a rule with a rule set id that doesn't exist. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void getSingleRuleFromNonExistentRuleSet()
{
STEP("Create a folder in existing site");
FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder();
STEP("Try to load rules for a non-existent rule set.");
restClient.authenticateUser(user).withCoreAPI().usingNode(folder).usingRuleSet("fake-id").getSingleRule("fake-rule-id");
restClient.assertStatusCodeIs(NOT_FOUND);
}
/** Check we get a 404 if trying to load an existing rule providing a wrong but existing folder */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void getSingleRuleFromWrongFolder()
{
STEP("Create a folder in existing site");
FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder();
STEP("Try to load a rule for a wrong but existing folder.");
restClient.authenticateUser(user).withCoreAPI().usingNode(folder).usingDefaultRuleSet().getSingleRule(createdRuleA.getId());
restClient.assertStatusCodeIs(NOT_FOUND);
}
/** Check we can get a rule by its id along with any included fields. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void getSingleRuleWithIncludedFields()
{
STEP("Load a particular rule");
RestRuleModel rule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.include("isShared")
.getSingleRule(createdRuleA.getId());
rule.assertThat().field("isShared").isNotNull();
}
/** Check that a user without read permission cannot view the folder rules. */
public void requireReadPermissionToGetRule()
{
STEP("Create a user and use them to create a private site containing a folder with a rule");
UserModel privateUser = dataUser.createRandomTestUser();
SiteModel privateSite = dataSite.usingUser(privateUser).createPrivateRandomSite();
FolderModel privateFolder = dataContent.usingUser(privateUser).usingSite(privateSite).createFolder();
RestRuleModel ruleModel = new RestRuleModel();
ruleModel.setName("Private site rule");
restClient.authenticateUser(privateUser).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
STEP("Try to get the rule with another user");
restClient.authenticateUser(user).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet().getListOfRules();
restClient.assertLastError()
.statusCodeIs(FORBIDDEN)
.containsSummary("Cannot read from this node");
}
/** Check that a user with only read permission can view the folder rules. */
public void dontRequireWritePermissionToGetRule()
{
STEP("Create a user and use them to create a private site containing a folder with a rule");
UserModel privateUser = dataUser.createRandomTestUser();
SiteModel privateSite = dataSite.usingUser(privateUser).createPrivateRandomSite();
FolderModel privateFolder = dataContent.usingUser(privateUser).usingSite(privateSite).createFolder();
RestRuleModel ruleModel = createRuleModel("Private site rule");
restClient.authenticateUser(privateUser).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
STEP("Create a collaborator in the private site");
UserModel collaborator = dataUser.createRandomTestUser();
collaborator.setUserRole(SiteCollaborator);
restClient.authenticateUser(privateUser).withCoreAPI().usingSite(privateSite).addPerson(collaborator);
STEP("Check the collaborator can view the rule");
RestRuleModelsCollection rules = restClient.authenticateUser(collaborator).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet().getListOfRules();
restClient.assertStatusCodeIs(OK);
rules.assertThat().entriesListContains("name", "Private site rule");
}
}

View File

@@ -0,0 +1,313 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.rules;
import static org.alfresco.rest.rules.RulesTestsUtils.createRuleModel;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import org.alfresco.dataprep.CMISUtil;
import org.alfresco.rest.RestTest;
import org.alfresco.rest.model.RestRuleModel;
import org.alfresco.rest.model.RestRuleModelsCollection;
import org.alfresco.rest.model.RestRuleSetLinkModel;
import org.alfresco.rest.model.RestRuleSetModel;
import org.alfresco.rest.model.RestRuleSetModelsCollection;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.SiteModel;
import org.alfresco.utility.model.TestGroup;
import org.alfresco.utility.model.UserModel;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* Tests for /nodes/{nodeId}/rule-set-links.
*/
@Test(groups = {TestGroup.RULES})
public class RuleSetLinksTests extends RestTest
{
private UserModel user;
private SiteModel site;
@BeforeClass(alwaysRun = true)
public void dataPreparation()
{
STEP("Create a user and site.");
user = dataUser.createRandomTestUser();
site = dataSite.usingUser(user).createPublicRandomSite();
}
/**
* Check we can link to folder containing a rule set.
*/
@Test(groups = {TestGroup.REST_API, TestGroup.RULES})
public void linkToFolderContainingRules()
{
STEP("Create folders in existing site");
final FolderModel ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder();
final FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder();
STEP("Create a rule in the rule folder.");
RestRuleModel ruleModel = createRuleModel("ruleName");
RestRuleModel rule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.createSingleRule(ruleModel);
STEP("Get the rule sets for the folder and find the rule set id");
final RestRuleSetModelsCollection ruleSets = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder)
.getListOfRuleSets();
ruleSets.assertThat().entriesListCountIs(1);
final String ruleSetId = ruleSets.getEntries().get(0).onModel().getId();
STEP("Link to a rule folder");
final RestRuleSetLinkModel request = new RestRuleSetLinkModel();
request.setId(ruleFolder.getNodeRef());
final RestRuleSetLinkModel ruleLink = restClient.authenticateUser(user).withCoreAPI().usingNode(folder).createRuleLink(request);
STEP("Assert link result");
restClient.assertStatusCodeIs(CREATED);
final RestRuleSetLinkModel expectedLink = new RestRuleSetLinkModel();
expectedLink.setId(ruleSetId);
ruleLink.assertThat().isEqualTo(expectedLink);
STEP("Check if folder returns same rules");
final RestRuleModelsCollection linkedRules = restClient.authenticateUser(user).withCoreAPI()
.usingNode(folder)
.usingDefaultRuleSet()
.getListOfRules();
linkedRules.assertThat().entriesListCountIs(1);
linkedRules.getEntries().get(0).onModel().assertThat().isEqualTo(rule);
STEP("Check if folder returns rule set with linked inclusionType");
final RestRuleSetModelsCollection linkedRuleSets = restClient.authenticateUser(user).withCoreAPI()
.usingNode(folder)
.include("inclusionType")
.getListOfRuleSets();
linkedRuleSets.assertThat().entriesListCountIs(1);
final RestRuleSetModel expectedRuleSet = new RestRuleSetModel();
expectedRuleSet.setId(ruleSetId);
expectedRuleSet.setInclusionType("linked");
linkedRuleSets.getEntries()
.get(0).onModel().assertThat().isEqualTo(expectedRuleSet);
}
/**
* Check we can link to a rule set.
*/
@Test(groups = {TestGroup.REST_API, TestGroup.RULES})
public void linkToRuleSet()
{
STEP("Create folders in existing site");
final FolderModel ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder();
final FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder();
STEP("Create a rule in the rule folder.");
RestRuleModel ruleModel = createRuleModel("ruleName");
RestRuleModel rule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.createSingleRule(ruleModel);
STEP("Get the rule sets for the folder and find the rule set id");
final RestRuleSetModelsCollection ruleSets = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder)
.getListOfRuleSets();
ruleSets.assertThat().entriesListCountIs(1);
final String ruleSetId = ruleSets.getEntries().get(0).onModel().getId();
STEP("Link to a rule set");
final RestRuleSetLinkModel request = new RestRuleSetLinkModel();
request.setId(ruleSetId);
final RestRuleSetLinkModel ruleLink = restClient.authenticateUser(user).withCoreAPI().usingNode(folder).createRuleLink(request);
STEP("Assert link result");
restClient.assertStatusCodeIs(CREATED);
final RestRuleSetLinkModel expectedLink = new RestRuleSetLinkModel();
expectedLink.setId(ruleSetId);
ruleLink.assertThat().isEqualTo(expectedLink);
STEP("Check if folder returns same rules");
final RestRuleModelsCollection linkedRules = restClient.authenticateUser(user).withCoreAPI()
.usingNode(folder)
.usingDefaultRuleSet()
.getListOfRules();
linkedRules.assertThat().entriesListCountIs(1);
linkedRules.getEntries().get(0).onModel().assertThat().isEqualTo(rule);
STEP("Check if folder returns rule set with linked inclusionType");
final RestRuleSetModelsCollection likedRuleSets = restClient.authenticateUser(user).withCoreAPI()
.usingNode(folder)
.include("inclusionType")
.getListOfRuleSets();
likedRuleSets.assertThat().entriesListCountIs(1);
final RestRuleSetModel expectedRuleSet = new RestRuleSetModel();
expectedRuleSet.setId(ruleSetId);
expectedRuleSet.setInclusionType("linked");
likedRuleSets.getEntries()
.get(0).onModel().assertThat().isEqualTo(expectedRuleSet);
}
/**
* Check we get 404 when linking to a non-existing rule set/folder.
*/
@Test(groups = {TestGroup.REST_API, TestGroup.RULES})
public void linkToNonExistingRuleSet()
{
STEP("Create a folder in existing site");
final FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder();
STEP("Link to non-existing rule set");
final RestRuleSetLinkModel request = new RestRuleSetLinkModel();
request.setId("dummy-rule-set-id");
restClient.authenticateUser(user).withCoreAPI().usingNode(folder).createRuleLink(request);
STEP("Assert link result is 404");
restClient.assertStatusCodeIs(NOT_FOUND);
}
/**
* Check we get bad request error when linking to a folder without rules.
*/
@Test(groups = {TestGroup.REST_API, TestGroup.RULES})
public void linkToFolderWithoutRules()
{
STEP("Create 2 folders without rules in existing site");
final FolderModel folder1 = dataContent.usingUser(user).usingSite(site).createFolder();
final FolderModel folder2 = dataContent.usingUser(user).usingSite(site).createFolder();
STEP("Link to a folder without rules");
final RestRuleSetLinkModel request = new RestRuleSetLinkModel();
request.setId(folder2.getNodeRef());
restClient.authenticateUser(user).withCoreAPI().usingNode(folder1).createRuleLink(request);
STEP("Assert link result is 400");
restClient.assertStatusCodeIs(BAD_REQUEST)
.assertLastError().containsSummary("The target node has no rules to link.");
}
/**
* Check we get bad request error when linking from a folder which already has rules.
*/
@Test(groups = {TestGroup.REST_API, TestGroup.RULES})
public void linkFromFolderWithRules()
{
STEP("Create folders in existing site");
final FolderModel folder1 = dataContent.usingUser(user).usingSite(site).createFolder();
final FolderModel folder2 = dataContent.usingUser(user).usingSite(site).createFolder();
STEP("Create rules in both folders.");
RestRuleModel ruleModel1 = createRuleModel("ruleName1");
restClient.authenticateUser(user).withCoreAPI().usingNode(folder1).usingDefaultRuleSet()
.createSingleRule(ruleModel1);
RestRuleModel ruleModel2 = createRuleModel("ruleName2");
restClient.authenticateUser(user).withCoreAPI().usingNode(folder2).usingDefaultRuleSet()
.createSingleRule(ruleModel2);
STEP("Link from a folder with rules");
final RestRuleSetLinkModel request = new RestRuleSetLinkModel();
request.setId(folder2.getNodeRef());
restClient.authenticateUser(user).withCoreAPI().usingNode(folder1).createRuleLink(request);
STEP("Assert link result is 400");
restClient.assertStatusCodeIs(BAD_REQUEST)
.assertLastError().containsSummary(
"Unable to link to a ruleset because the folder has pre-existing rules or is already linked to a ruleset.");
}
/**
* Check we get bad request error when linking to a file node.
*/
@Test(groups = {TestGroup.REST_API, TestGroup.RULES})
public void linkToFileNode()
{
STEP("Create a folder in existing site");
final FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder();
final FileModel fileContent = dataContent.usingUser(user).usingSite(site).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
STEP("Link to a file node");
final RestRuleSetLinkModel request = new RestRuleSetLinkModel();
request.setId(fileContent.getNodeRef());
restClient.authenticateUser(user).withCoreAPI().usingNode(folder).createRuleLink(request);
STEP("Assert link result is 400");
restClient.assertStatusCodeIs(BAD_REQUEST)
.assertLastError().containsSummary("NodeId of a folder is expected!");
}
/**
* Check we can link to a parent folder with rules.
*/
@Test(groups = {TestGroup.REST_API, TestGroup.RULES})
public void linkToParentNodeWithRules()
{
STEP("Create parent/child folders in existing site");
final FolderModel parentFolder = dataContent.usingUser(user).usingSite(site).createFolder();
final FolderModel childFolder = dataContent.usingUser(user).usingSite(site).usingResource(parentFolder).createFolder();
STEP("Create a rule in the parent folder.");
RestRuleModel ruleModel = createRuleModel("ruleName");
RestRuleModel rule = restClient.authenticateUser(user).withCoreAPI().usingNode(parentFolder).usingDefaultRuleSet()
.createSingleRule(ruleModel);
STEP("Get the rule sets for the folder and find the rule set id");
final RestRuleSetModelsCollection ruleSets = restClient.authenticateUser(user).withCoreAPI().usingNode(parentFolder)
.getListOfRuleSets();
ruleSets.assertThat().entriesListCountIs(1);
final String ruleSetId = ruleSets.getEntries().get(0).onModel().getId();
STEP("Link to the parent folder");
final RestRuleSetLinkModel request = new RestRuleSetLinkModel();
request.setId(parentFolder.getNodeRef());
final RestRuleSetLinkModel ruleLink = restClient.authenticateUser(user).withCoreAPI().usingNode(childFolder).createRuleLink(request);
STEP("Assert link result");
restClient.assertStatusCodeIs(CREATED);
final RestRuleSetLinkModel expectedLink = new RestRuleSetLinkModel();
expectedLink.setId(ruleSetId);
ruleLink.assertThat().isEqualTo(expectedLink);
STEP("Check if child folder returns same rules");
final RestRuleModelsCollection linkedRules = restClient.authenticateUser(user).withCoreAPI()
.usingNode(childFolder)
.usingDefaultRuleSet()
.getListOfRules();
linkedRules.assertThat().entriesListCountIs(1);
linkedRules.getEntries().get(0).onModel().assertThat().isEqualTo(rule);
STEP("Check if child folder returns rule set with linked inclusionType");
final RestRuleSetModelsCollection linkedRuleSets = restClient.authenticateUser(user).withCoreAPI()
.usingNode(childFolder)
.include("inclusionType")
.getListOfRuleSets();
linkedRuleSets.assertThat().entriesListCountIs(1);
final RestRuleSetModel expectedRuleSet = new RestRuleSetModel();
expectedRuleSet.setId(ruleSetId);
expectedRuleSet.setInclusionType("linked");
linkedRuleSets.getEntries()
.get(0).onModel().assertThat().isEqualTo(expectedRuleSet);
}
}

View File

@@ -0,0 +1,130 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2022 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.rules;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.rest.model.RestActionBodyExecTemplateModel;
import org.alfresco.rest.model.RestCompositeConditionDefinitionModel;
import org.alfresco.rest.model.RestRuleModel;
public class RulesTestsUtils
{
static final String RULE_NAME_DEFAULT = "ruleName";
static final String RULE_DESCRIPTION_DEFAULT = "rule description";
static final boolean RULE_ENABLED_DEFAULT = true;
static final boolean RULE_CASCADE_DEFAULT = true;
static final boolean RULE_ASYNC_DEFAULT = true;
static final boolean RULE_SHARED_DEFAULT = false;
static final String RULE_ERROR_SCRIPT_DEFAULT = "error-script";
static final List<String> ruleTriggersDefault = List.of("inbound", "update", "outbound");
/**
* Create a rule model filled with default values.
*
* @return The created rule model.
*/
public static RestRuleModel createRuleModelWithModifiedValues()
{
RestRuleModel ruleModel = createRuleModelWithDefaultValues();
ruleModel.setDescription(RULE_DESCRIPTION_DEFAULT);
ruleModel.setEnabled(RULE_ENABLED_DEFAULT);
ruleModel.setCascade(RULE_CASCADE_DEFAULT);
ruleModel.setAsynchronous(RULE_ASYNC_DEFAULT);
ruleModel.setIsShared(RULE_SHARED_DEFAULT);
ruleModel.setTriggers(ruleTriggersDefault);
ruleModel.setErrorScript(RULE_ERROR_SCRIPT_DEFAULT);
return ruleModel;
}
public static RestRuleModel createRuleModelWithDefaultValues()
{
return createRuleModel(RULE_NAME_DEFAULT, List.of(createDefaultActionModel()));
}
public static RestRuleModel createRuleModel(String name)
{
return createRuleModel(name, List.of(createDefaultActionModel()));
}
/**
* Create a rule model.
*
* @param name The name for the rule.
* @param restActionModels Rule's actions.
* @return The created rule model.
*/
public static RestRuleModel createRuleModel(String name, List<RestActionBodyExecTemplateModel> restActionModels)
{
RestRuleModel ruleModel = new RestRuleModel();
ruleModel.setName(name);
ruleModel.setActions(restActionModels);
return ruleModel;
}
/**
* Create a rule's action model.
*
* @return The created action model.
*/
public static RestActionBodyExecTemplateModel createDefaultActionModel()
{
RestActionBodyExecTemplateModel restActionModel = new RestActionBodyExecTemplateModel();
restActionModel.setActionDefinitionId("set-property-value");
restActionModel.setParams(Map.of("aspect-name", "cm:audio"));
return restActionModel;
}
public static List<RestActionBodyExecTemplateModel> addActionContextParams(List<RestActionBodyExecTemplateModel> inputActions)
{
inputActions.forEach(inputAction -> {
final Map<String, Serializable> params = new HashMap<>((Map<String, Serializable>) inputAction.getParams());
params.put("actionContext", "rule");
inputAction.setParams(params);
});
return inputActions;
}
public static RestActionBodyExecTemplateModel createCustomActionModel(String actionDefinitionId, Map<String, Serializable> params)
{
RestActionBodyExecTemplateModel restActionModel = new RestActionBodyExecTemplateModel();
restActionModel.setActionDefinitionId(actionDefinitionId);
restActionModel.setParams(params);
return restActionModel;
}
public static RestCompositeConditionDefinitionModel createEmptyConditionModel()
{
RestCompositeConditionDefinitionModel conditions = new RestCompositeConditionDefinitionModel();
conditions.setInverted(false);
conditions.setBooleanMode("and");
return conditions;
}
}

View File

@@ -0,0 +1,232 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2022 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.rules;
import static org.alfresco.rest.requests.RuleSettings.IS_INHERITANCE_ENABLED;
import static org.alfresco.utility.constants.UserRole.SiteCollaborator;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import static org.springframework.http.HttpStatus.OK;
import org.alfresco.rest.RestTest;
import org.alfresco.rest.model.RestRuleSettingsModel;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.SiteModel;
import org.alfresco.utility.model.TestGroup;
import org.alfresco.utility.model.UserModel;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* Tests for GET and PUT /nodes/{nodeId}/rule-settings/{ruleSettingKey}.
*/
@Test (groups = { TestGroup.RULES })
public class SetInheritanceTests extends RestTest
{
private UserModel siteOwner;
private SiteModel site;
@BeforeClass (alwaysRun = true)
public void dataPreparation()
{
STEP("Create a user, site and folder.");
siteOwner = dataUser.createRandomTestUser();
site = dataSite.usingUser(siteOwner).createPrivateRandomSite();
}
/** Check we can get the -isInheritanceEnabled- rule setting for the folder. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void getIsInherited()
{
STEP("Create a folder for the test.");
FolderModel folder = dataContent.usingUser(siteOwner).usingSite(site).createFolder();
STEP("Get the -isInheritanceEnabled- rule settings for the folder.");
RestRuleSettingsModel ruleSettingsModel = restClient.authenticateUser(siteOwner)
.withCoreAPI()
.usingResource(folder)
.usingIsInheritanceEnabledRuleSetting()
.retrieveSetting();
restClient.assertStatusCodeIs(OK);
RestRuleSettingsModel expected = new RestRuleSettingsModel();
expected.setKey(IS_INHERITANCE_ENABLED);
expected.setValue(true);
ruleSettingsModel.assertThat().isEqualTo(expected);
}
/** Check we get an error when trying to get settings from a non-existent folder. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void getIsInheritedFromNonExistentFolder()
{
STEP("Try to get the -isInheritanceEnabled- rule settings for a fake folder.");
FolderModel nonExistentFolder = FolderModel.getRandomFolderModel();
nonExistentFolder.setNodeRef("fake-id");
restClient.authenticateUser(siteOwner)
.withCoreAPI()
.usingResource(nonExistentFolder)
.usingIsInheritanceEnabledRuleSetting()
.retrieveSetting();
restClient.assertLastError().statusCodeIs(NOT_FOUND)
.containsSummary("The entity with id: fake-id was not found");
}
/** Check we get an error when trying to retrieve a non-existent setting. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void getNonExistentSetting()
{
STEP("Create a folder for the test.");
FolderModel folder = dataContent.usingUser(siteOwner).usingSite(site).createFolder();
STEP("Try to get a fake setting from the folder.");
restClient.authenticateUser(siteOwner).withCoreAPI().usingResource(folder).usingRuleSetting("-fakeRuleSetting-")
.retrieveSetting();
restClient.assertLastError().statusCodeIs(NOT_FOUND)
.containsSummary("Unrecognised rule setting key -fakeRuleSetting-");
}
/** Check a user without permission for the folder cannot get the -isInheritanceEnabled- rule setting. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void getIsInheritedWithoutPermission()
{
STEP("Create a folder and a user without permission to access it.");
FolderModel folder = dataContent.usingUser(siteOwner).usingSite(site).createFolder();
UserModel noPermissionUser = dataUser.createRandomTestUser();
STEP("Try to get the -isInheritanceEnabled- setting without permission.");
restClient.authenticateUser(noPermissionUser)
.withCoreAPI()
.usingResource(folder)
.usingIsInheritanceEnabledRuleSetting()
.retrieveSetting();
restClient.assertLastError().statusCodeIs(FORBIDDEN)
.containsSummary("Cannot read from this node");
}
/** Check we can change the -isInheritanceEnabled- rule setting for the folder. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void updateIsInherited()
{
STEP("Create a folder for the test.");
FolderModel folder = dataContent.usingUser(siteOwner).usingSite(site).createFolder();
STEP("Set -isInheritanceEnabled- to false.");
RestRuleSettingsModel updateBody = new RestRuleSettingsModel();
updateBody.setValue(false);
RestRuleSettingsModel ruleSettingsModel = restClient.authenticateUser(siteOwner)
.withCoreAPI()
.usingResource(folder)
.usingIsInheritanceEnabledRuleSetting()
.updateSetting(updateBody);
restClient.assertStatusCodeIs(OK);
RestRuleSettingsModel expected = new RestRuleSettingsModel();
expected.setKey(IS_INHERITANCE_ENABLED);
expected.setValue(false);
ruleSettingsModel.assertThat().isEqualTo(expected);
}
/** Check we get an error when trying to set -isInheritanceEnabled- to something other than a boolean. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void updateInheritedWithBadValue()
{
STEP("Create a folder for the test.");
FolderModel folder = dataContent.usingUser(siteOwner).usingSite(site).createFolder();
STEP("Try to set -isInheritanceEnabled- to \"banana\".");
RestRuleSettingsModel updateBody = new RestRuleSettingsModel();
updateBody.setValue("banana");
restClient.authenticateUser(siteOwner).withCoreAPI().usingResource(folder).usingIsInheritanceEnabledRuleSetting()
.updateSetting(updateBody);
restClient.assertLastError().statusCodeIs(BAD_REQUEST)
.containsSummary("Rule setting " + IS_INHERITANCE_ENABLED + " requires a boolean value.");
}
/** Check we get an error when the folder is not found. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void updateInheritedWithNonExistentFolder()
{
STEP("Try to set -isInheritanceEnabled- against a fake folder.");
FolderModel nonExistentFolder = FolderModel.getRandomFolderModel();
nonExistentFolder.setNodeRef("fake-id");
RestRuleSettingsModel updateBody = new RestRuleSettingsModel();
updateBody.setValue(true);
restClient.authenticateUser(siteOwner).withCoreAPI().usingResource(nonExistentFolder).usingIsInheritanceEnabledRuleSetting()
.updateSetting(updateBody);
restClient.assertLastError().statusCodeIs(NOT_FOUND)
.containsSummary("The entity with id: fake-id was not found");
}
/** Check we get an error when trying to set a non-existent setting. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void updateNonExistentSetting()
{
STEP("Create a folder for the test.");
FolderModel folder = dataContent.usingUser(siteOwner).usingSite(site).createFolder();
STEP("Try to set a fake setting on the folder.");
RestRuleSettingsModel updateBody = new RestRuleSettingsModel();
updateBody.setValue(true);
restClient.authenticateUser(siteOwner).withCoreAPI().usingResource(folder).usingRuleSetting("-fakeRuleSetting-")
.updateSetting(updateBody);
restClient.assertLastError().statusCodeIs(NOT_FOUND)
.containsSummary("Unrecognised rule setting key -fakeRuleSetting-");
}
/** Check a user without manage permission cannot update the -isInheritanceEnabled- rule setting. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void updateIsInheritedWithoutPermission()
{
STEP("Create a folder and a collaborator.");
FolderModel folder = dataContent.usingUser(siteOwner).usingSite(site).createFolder();
UserModel collaborator = dataUser.createRandomTestUser();
collaborator.setUserRole(SiteCollaborator);
restClient.authenticateUser(siteOwner).withCoreAPI().usingSite(site).addPerson(collaborator);
STEP("Try to update the -isInheritanceEnabled- setting without permission.");
RestRuleSettingsModel updateBody = new RestRuleSettingsModel();
updateBody.setValue(true);
restClient.authenticateUser(collaborator).withCoreAPI().usingResource(folder).usingIsInheritanceEnabledRuleSetting()
.updateSetting(updateBody);
restClient.assertLastError().statusCodeIs(FORBIDDEN)
.containsSummary("Insufficient permissions to manage rules");
}
}

View File

@@ -0,0 +1,220 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2022 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.rules;
import static org.alfresco.rest.rules.RulesTestsUtils.createDefaultActionModel;
import static org.alfresco.rest.rules.RulesTestsUtils.createRuleModel;
import static org.alfresco.utility.constants.UserRole.SiteCollaborator;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import static org.springframework.http.HttpStatus.OK;
import java.util.List;
import org.alfresco.rest.RestTest;
import org.alfresco.rest.model.RestActionBodyExecTemplateModel;
import org.alfresco.rest.model.RestRuleModel;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.SiteModel;
import org.alfresco.utility.model.TestGroup;
import org.alfresco.utility.model.UserModel;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* Tests for PUT /nodes/{nodeId}/rule-sets/{ruleSetId}/rules.
*/
@Test (groups = { TestGroup.RULES })
public class UpdateRulesTests extends RestTest
{
private UserModel user;
private SiteModel site;
private FolderModel ruleFolder;
@BeforeClass (alwaysRun = true)
public void dataPreparation()
{
user = dataUser.createRandomTestUser();
site = dataSite.usingUser(user).createPublicRandomSite();
ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder();
}
/**
* Check we can update a rule.
* <p>
* Also check that the isShared field is not returned when not requested.
*/
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void updateRule()
{
RestRuleModel rule = createAndSaveRule("Rule name");
STEP("Try to update the rule.");
RestRuleModel updatedRuleModel = createRuleModel("Updated rule name");
RestRuleModel updatedRule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.updateRule(rule.getId(), updatedRuleModel);
restClient.assertStatusCodeIs(OK);
updatedRule.assertThat().field("id").is(rule.getId())
.assertThat().field("name").is("Updated rule name")
.assertThat().field("isShared").isNull();
}
/** Check we get a 404 if trying to update a rule in a folder that doesn't exist. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void updateRuleForNonExistentFolder()
{
RestRuleModel rule = createAndSaveRule("Rule name");
STEP("Try to update a rule in a non-existent folder.");
FolderModel nonExistentFolder = FolderModel.getRandomFolderModel();
nonExistentFolder.setNodeRef("fake-id");
RestRuleModel updatedRuleModel = new RestRuleModel();
updatedRuleModel.setName("Updated rule name");
restClient.authenticateUser(user).withCoreAPI().usingNode(nonExistentFolder).usingDefaultRuleSet()
.updateRule(rule.getId(), updatedRuleModel);
restClient.assertLastError().statusCodeIs(NOT_FOUND)
.containsSummary("fake-id was not found");
}
/** Check we get a 404 if trying to update a rule in a rule set that doesn't exist. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void updateRuleForNonExistentRuleSet()
{
RestRuleModel rule = createAndSaveRule("Rule name");
STEP("Try to update a rule in a non-existent rule set.");
RestRuleModel updatedRuleModel = new RestRuleModel();
updatedRuleModel.setName("Updated rule name");
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingRuleSet("fake-id")
.updateRule(rule.getId(), updatedRuleModel);
restClient.assertLastError().statusCodeIs(NOT_FOUND)
.containsSummary("fake-id was not found");
}
/** Check we get a 404 if trying to update a rule that doesn't exist. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void updateRuleForNonExistentRuleId()
{
STEP("Try to update a rule that doesn't exist.");
RestRuleModel updatedRuleModel = new RestRuleModel();
updatedRuleModel.setName("Updated rule name");
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.updateRule("fake-id", updatedRuleModel);
restClient.assertLastError().statusCodeIs(NOT_FOUND)
.containsSummary("fake-id was not found");
}
/** Check that a user without permission cannot update a rule. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void requirePermissionToUpdateRule()
{
STEP("Create a user and use them to create a private site containing a folder");
UserModel privateUser = dataUser.createRandomTestUser();
SiteModel privateSite = dataSite.usingUser(privateUser).createPrivateRandomSite();
FolderModel privateFolder = dataContent.usingUser(privateUser).usingSite(privateSite).createFolder();
STEP("Create a collaborator and check they don't have permission to create a rule");
UserModel collaborator = dataUser.createRandomTestUser();
dataUser.addUserToSite(collaborator, privateSite, SiteCollaborator);
RestRuleModel ruleModel = new RestRuleModel();
ruleModel.setName("ruleName");
restClient.authenticateUser(user).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
restClient.assertStatusCodeIs(FORBIDDEN);
restClient.assertLastError().containsSummary("Insufficient permissions to manage rules");
}
/** Check we get an error trying to update a rule to have no name. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void updateRuleToHaveEmptyName()
{
RestRuleModel rule = createAndSaveRule("Rule name");
STEP("Try to update the rule to have no name.");
RestRuleModel updatedRuleModel = createRuleModel("");
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().updateRule(rule.getId(), updatedRuleModel);
restClient.assertLastError().statusCodeIs(BAD_REQUEST)
.containsSummary("Rule name is a mandatory parameter");
}
/** Check that updates to the rule's id are ignored. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
public void tryToUpdateRuleId()
{
RestRuleModel rule = createAndSaveRule("Rule name");
STEP("Try to update the rule id and check it isn't changed.");
RestRuleModel updatedRuleModel = createRuleModel("Rule name");
updatedRuleModel.setId("new-rule-id");
RestRuleModel updatedRule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.updateRule(rule.getId(), updatedRuleModel);
updatedRule.assertThat().field("id").is(rule.getId());
}
/** Check we can update a rule and get the included fields. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void updateRuleWithIncludedFields()
{
RestRuleModel rule = createAndSaveRule("Rule name");
STEP("Try to update the rule.");
RestRuleModel updatedRuleModel = createRuleModel("Updated rule name");
RestRuleModel updatedRule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.include("isShared")
.updateRule(rule.getId(), updatedRuleModel);
updatedRule.assertThat().field("isShared").isNotNull();
}
private RestRuleModel createAndSaveRule(String name)
{
return createAndSaveRule(name, List.of(createDefaultActionModel()));
}
/**
* Create a rule for folder and store it.
*
* @param name The name for the rule.
* @param restActionModels Rule's actions.
* @return The created rule.
*/
private RestRuleModel createAndSaveRule(String name, List<RestActionBodyExecTemplateModel> restActionModels)
{
STEP("Create a rule called " + name + ", containing actions: " + restActionModels);
RestRuleModel ruleModel = createRuleModel(name, restActionModels);
return restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.createSingleRule(ruleModel);
}
}

View File

@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="REST API tests part1" preserve-order="true">
<listeners>
<listeners>
<listener class-name="org.alfresco.utility.report.HtmlReportListener"/>
<listener class-name="org.alfresco.utility.testrail.TestRailExecutorListener"/>
<listener class-name="org.alfresco.utility.testng.OSTestMethodSelector"/>
</listeners>
</listeners>
<test name="Part1">
<packages>
@@ -14,6 +14,7 @@
<package name="org.alfresco.rest.comments.*"/>
<package name="org.alfresco.rest.downloads.*"/>
<package name="org.alfresco.rest.favorites.*"/>
<package name="org.alfresco.rest.rules.*" />
<package name="org.alfresco.rest.servlet.*"/>
</packages>
</test>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<developers>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<properties>

71
pom.xml
View File

@@ -2,7 +2,7 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>alfresco-community-repo</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Alfresco Community Repo Parent</name>
@@ -45,18 +45,18 @@
<dependency.alfresco-hb-data-sender.version>1.0.12</dependency.alfresco-hb-data-sender.version>
<dependency.alfresco-trashcan-cleaner.version>2.4.1</dependency.alfresco-trashcan-cleaner.version>
<dependency.alfresco-jlan.version>7.1</dependency.alfresco-jlan.version>
<dependency.alfresco-jlan.version>7.2</dependency.alfresco-jlan.version>
<dependency.alfresco-server-root.version>6.0.1</dependency.alfresco-server-root.version>
<dependency.alfresco-messaging-repo.version>1.2.19</dependency.alfresco-messaging-repo.version>
<dependency.alfresco-messaging-repo.version>1.2.20</dependency.alfresco-messaging-repo.version>
<dependency.alfresco-log-sanitizer.version>0.2</dependency.alfresco-log-sanitizer.version>
<dependency.activiti-engine.version>5.23.0</dependency.activiti-engine.version>
<dependency.activiti.version>5.23.0</dependency.activiti.version>
<dependency.alfresco-transform-service.version>1.5.3</dependency.alfresco-transform-service.version>
<dependency.alfresco-transform-core.version>2.6.0</dependency.alfresco-transform-core.version>
<dependency.alfresco-greenmail.version>6.2</dependency.alfresco-greenmail.version>
<dependency.acs-event-model.version>0.0.15</dependency.acs-event-model.version>
<dependency.alfresco-transform-service.version>1.5.4-A3</dependency.alfresco-transform-service.version>
<dependency.alfresco-transform-core.version>2.7.0-A1</dependency.alfresco-transform-core.version>
<dependency.alfresco-greenmail.version>6.4</dependency.alfresco-greenmail.version>
<dependency.acs-event-model.version>0.0.16</dependency.acs-event-model.version>
<dependency.spring.version>5.3.21</dependency.spring.version>
<dependency.spring.version>5.3.22</dependency.spring.version>
<dependency.antlr.version>3.5.2</dependency.antlr.version>
<dependency.jackson.version>2.13.3</dependency.jackson.version>
<dependency.jackson-databind.version>2.13.3</dependency.jackson-databind.version>
@@ -74,18 +74,18 @@
<dependency.httpcore.version>4.4.15</dependency.httpcore.version>
<dependency.commons-httpclient.version>3.1-HTTPCLIENT-1265</dependency.commons-httpclient.version>
<dependency.xercesImpl.version>2.12.2</dependency.xercesImpl.version>
<dependency.slf4j.version>1.7.35</dependency.slf4j.version>
<dependency.slf4j.version>1.7.36</dependency.slf4j.version>
<dependency.gytheio.version>0.16</dependency.gytheio.version>
<dependency.groovy.version>3.0.11</dependency.groovy.version>
<dependency.groovy.version>3.0.12</dependency.groovy.version>
<dependency.tika.version>2.4.1</dependency.tika.version>
<dependency.spring-security.version>5.7.2</dependency.spring-security.version>
<dependency.truezip.version>7.7.10</dependency.truezip.version>
<dependency.poi.version>5.2.2</dependency.poi.version>
<dependency.ooxml-schemas.version>1.4</dependency.ooxml-schemas.version>
<dependency.keycloak.version>15.0.2</dependency.keycloak.version>
<dependency.keycloak.version>18.0.0</dependency.keycloak.version>
<dependency.jboss.logging.version>3.5.0.Final</dependency.jboss.logging.version>
<dependency.camel.version>3.15.0</dependency.camel.version> <!-- when bumping this version, please keep track/sync with included netty.io dependencies (can cause dependency conflicts)-->
<dependency.activemq.version>5.16.1</dependency.activemq.version>
<dependency.activemq.version>5.17.1</dependency.activemq.version>
<dependency.apache-compress.version>1.21</dependency.apache-compress.version>
<dependency.apache.taglibs.version>1.2.5</dependency.apache.taglibs.version>
<dependency.awaitility.version>4.2.0</dependency.awaitility.version>
@@ -109,22 +109,22 @@
<alfresco.googledrive.version>3.2.2</alfresco.googledrive.version>
<alfresco.aos-module.version>1.4.1</alfresco.aos-module.version>
<alfresco.api-explorer.version>7.2.0</alfresco.api-explorer.version> <!-- Also in alfresco-enterprise-share -->
<alfresco.api-explorer.version>7.2.1</alfresco.api-explorer.version> <!-- Also in alfresco-enterprise-share -->
<alfresco.maven-plugin.version>2.2.0</alfresco.maven-plugin.version>
<license-maven-plugin.version>2.0.1.alfresco-2</license-maven-plugin.version>
<dependency.postgresql.version>42.4.0</dependency.postgresql.version>
<dependency.mysql.version>8.0.29</dependency.mysql.version>
<dependency.postgresql.version>42.4.1</dependency.postgresql.version>
<dependency.mysql.version>8.0.30</dependency.mysql.version>
<dependency.mysql-image.version>8</dependency.mysql-image.version>
<dependency.mariadb.version>2.7.4</dependency.mariadb.version>
<dependency.tas-utility.version>3.0.48</dependency.tas-utility.version>
<dependency.rest-assured.version>3.3.0</dependency.rest-assured.version>
<dependency.tas-restapi.version>1.87</dependency.tas-restapi.version>
<dependency.tas-cmis.version>1.31</dependency.tas-cmis.version>
<dependency.tas-email.version>1.8</dependency.tas-email.version>
<dependency.tas-webdav.version>1.6</dependency.tas-webdav.version>
<dependency.tas-ftp.version>1.5</dependency.tas-ftp.version>
<dependency.tas-utility.version>3.0.49</dependency.tas-utility.version>
<dependency.rest-assured.version>5.1.1</dependency.rest-assured.version>
<dependency.tas-restapi.version>1.115</dependency.tas-restapi.version>
<dependency.tas-cmis.version>1.32</dependency.tas-cmis.version>
<dependency.tas-email.version>1.9</dependency.tas-email.version>
<dependency.tas-webdav.version>1.7</dependency.tas-webdav.version>
<dependency.tas-ftp.version>1.7</dependency.tas-ftp.version>
<dependency.tas-dataprep.version>2.6</dependency.tas-dataprep.version>
<!-- AGS properties shared between community and enterprise -->
@@ -148,7 +148,7 @@
<connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
<developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
<url>https://github.com/Alfresco/alfresco-community-repo</url>
<tag>17.49</tag>
<tag>HEAD</tag>
</scm>
<distributionManagement>
@@ -616,6 +616,12 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-reload4j</artifactId>
<version>${dependency.slf4j.version}</version>
<exclusions>
<exclusion>
<groupId>ch.qos.reload4j</groupId>
<artifactId>reload4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>xerces</groupId>
@@ -639,7 +645,7 @@
<dependency>
<groupId>com.github.junrar</groupId>
<artifactId>junrar</artifactId>
<version>7.5.2</version>
<version>7.5.3</version>
</dependency>
<dependency>
<groupId>com.github.fge</groupId>
@@ -877,6 +883,17 @@
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>${dependency.activiti.version}</version>
<exclusions>
<exclusion>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>
@@ -894,7 +911,7 @@
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.40.1</version>
<version>0.40.2</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
@@ -920,7 +937,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.2.0</version>
<version>3.3.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -929,7 +946,7 @@
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.4.1</version>
<version>3.4.2</version>
</plugin>
<plugin>
<groupId>org.alfresco.maven.plugin</groupId>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>17.49</version>
<version>17.102-SNAPSHOT</version>
</parent>
<dependencies>
@@ -130,7 +130,7 @@
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>8.2.0.v20160908</version>
<version>10.0.11</version>
<scope>test</scope>
<exclusions>
<exclusion>
@@ -142,19 +142,19 @@
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-security</artifactId>
<version>8.2.0.v20160908</version>
<version>10.0.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>8.2.0.v20160908</version>
<version>10.0.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.alfresco.cmis.client</groupId>
<artifactId>alfresco-opencmis-extension</artifactId>
<version>2.0</version>
<version>2.1</version>
<scope>test</scope>
<exclusions>
<!-- Duplicates classes from jakarta.transaction:jakarta.transaction-api -->

View File

@@ -0,0 +1,64 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.repo.web.scripts;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.MimetypeService;
import org.springframework.extensions.webscripts.WebScriptRequest;
public class MimeTypeUtil
{
/**
* Get the file mimetype from the file ContentReader, and if its null then set the mimetype to binary by default
* and try to get the correct one from file extension
*
*
* @param reader reader of the file in the request
* @param req request relating to the file
* @param mimetypeService MimetypeService
*
* @return mimetype of the file as a string
*/
public static String determineMimetype(ContentReader reader, WebScriptRequest req, MimetypeService mimetypeService)
{
String mimetype = reader.getMimetype();
if (mimetype == null || mimetype.length() == 0)
{
String extensionPath = req.getExtensionPath();
mimetype = MimetypeMap.MIMETYPE_BINARY;
int extIndex = extensionPath.lastIndexOf('.');
if (extIndex != -1)
{
String ext = extensionPath.substring(extIndex + 1);
mimetype = mimetypeService.getMimetype(ext);
}
}
return mimetype;
}
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* Copyright (C) 2005 - 2022 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -26,14 +26,18 @@
package org.alfresco.repo.web.scripts.content;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.web.scripts.MimeTypeUtil;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.NamespaceService;
@@ -65,6 +69,19 @@ public class ContentGet extends StreamContent implements ServletContextAware
private NamespaceService namespaceService;
private ContentService contentService;
private List<String> nonAttachContentTypes = Collections.emptyList();
/**
* @param nonAttachContentTypes List<String>
*/
public void setNonAttachContentTypes(List<String> nonAttachContentTypes)
{
if (nonAttachContentTypes != null && !nonAttachContentTypes.isEmpty())
{
this.nonAttachContentTypes = nonAttachContentTypes;
}
}
/**
* @param servletContext ServletContext
*/
@@ -121,9 +138,7 @@ public class ContentGet extends StreamContent implements ServletContextAware
{
throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find " + reference.toString());
}
// determine attachment
boolean attach = Boolean.valueOf(req.getParameter("a"));
// render content
QName propertyQName = ContentModel.PROP_CONTENT;
@@ -140,6 +155,19 @@ public class ContentGet extends StreamContent implements ServletContextAware
propertyQName = QName.createQName(propertyName, namespaceService);
}
}
// determine attachment and force download for specific mimetypes - see PRODSEC-5862
boolean attach = Boolean.valueOf(req.getParameter("a"));
ContentReader reader = contentService.getReader(nodeRef, propertyQName);
String mimetype = MimeTypeUtil.determineMimetype(reader, req, mimetypeService);
if (!attach)
{
if (nonAttachContentTypes == null || !nonAttachContentTypes.contains(mimetype))
{
attach = true;
logger.warn("Ignored a=false for " + nodeRef.getId() + " since " + mimetype + " is not in the whitelist for non-attach content types");
}
}
// Stream the content
streamContentLocal(req, res, nodeRef, attach, propertyQName, null);

View File

@@ -1,28 +1,28 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.repo.web.scripts.content;
import java.io.IOException;
@@ -33,7 +33,7 @@ import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.web.scripts.MimeTypeUtil;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
@@ -79,18 +79,7 @@ public class ContentInfo extends StreamContent
delegate.setAttachment(req, res, attach, attachFileName);
// establish mimetype
String mimetype = reader.getMimetype();
String extensionPath = req.getExtensionPath();
if (mimetype == null || mimetype.length() == 0)
{
mimetype = MimetypeMap.MIMETYPE_BINARY;
int extIndex = extensionPath.lastIndexOf('.');
if (extIndex != -1)
{
String ext = extensionPath.substring(extIndex + 1);
mimetype = mimetypeService.getMimetype(ext);
}
}
String mimetype = MimeTypeUtil.determineMimetype(reader, req, mimetypeService);
// set mimetype for the content and the character encoding + length for the stream
res.setContentType(mimetype);

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* Copyright (C) 2005 - 2022 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -30,6 +30,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.SocketException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
@@ -43,6 +44,7 @@ import javax.servlet.http.HttpServletResponse;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.filestore.FileContentReader;
import org.alfresco.repo.web.scripts.MimeTypeUtil;
import org.alfresco.sync.repo.events.EventPublisher;
import org.alfresco.repo.web.util.HttpRangeProcessor;
import org.alfresco.rest.framework.resource.content.CacheDirective;
@@ -58,6 +60,7 @@ import org.alfresco.service.namespace.QName;
import org.alfresco.util.TempFileProvider;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.cxf.attachment.Rfc5987Util;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.ResourceLoader;
import org.springframework.extensions.webscripts.Cache;
@@ -361,18 +364,7 @@ public class ContentStreamer implements ResourceLoaderAware
setAttachment(req, res, attach, attachFileName);
// establish mimetype
String mimetype = reader.getMimetype();
String extensionPath = req.getExtensionPath();
if (mimetype == null || mimetype.length() == 0)
{
mimetype = MimetypeMap.MIMETYPE_BINARY;
int extIndex = extensionPath.lastIndexOf('.');
if (extIndex != -1)
{
String ext = extensionPath.substring(extIndex + 1);
mimetype = mimetypeService.getMimetype(ext);
}
}
String mimetype = MimeTypeUtil.determineMimetype(reader, req, mimetypeService);
res.setHeader(HEADER_ACCEPT_RANGES, "bytes");
try
@@ -482,7 +474,7 @@ public class ContentStreamer implements ResourceLoaderAware
if (req == null)
{
headerValue += "; filename*=UTF-8''" + URLEncoder.encode(attachFileName, StandardCharsets.UTF_8)
headerValue += "; filename*=UTF-8''" + encodeFilename(attachFileName)
+ "; filename=\"" + filterNameForQuotedString(attachFileName) + "\"";
}
else
@@ -491,12 +483,12 @@ public class ContentStreamer implements ResourceLoaderAware
boolean isLegacy = (null != userAgent) && (userAgent.contains("MSIE 8") || userAgent.contains("MSIE 7"));
if (isLegacy)
{
headerValue += "; filename=\"" + URLEncoder.encode(attachFileName, StandardCharsets.UTF_8);
headerValue += "; filename=\"" + encodeFilename(attachFileName);
}
else
{
headerValue += "; filename=\"" + filterNameForQuotedString(attachFileName) + "\"; filename*=UTF-8''"
+ URLEncoder.encode(attachFileName, StandardCharsets.UTF_8);
+ encodeFilename(attachFileName);
}
}
}
@@ -506,6 +498,21 @@ public class ContentStreamer implements ResourceLoaderAware
res.setHeader("Content-Disposition", headerValue);
}
}
private String encodeFilename(String attachFileName)
{
try
{
return Rfc5987Util.encode(attachFileName);
}
catch (UnsupportedEncodingException e)
{
if (logger.isInfoEnabled())
logger.info(e.getMessage() + " Changing encoder from Rfc5987Util to java.net.URLEncoder.");
return URLEncoder.encode(attachFileName, StandardCharsets.UTF_8);
}
}
protected String filterNameForQuotedString(String s)
{

View File

@@ -78,7 +78,7 @@ public abstract class AbstractRuleWebScript extends DeclarativeWebScript
private static final String RULE_OUTBOUND = "outbound";
private static final String ACTION_CHECK_OUT = "check-out";
private static final String CANNOT_CREATE_RULE = "cannot.create.rule.checkout.outbound";
public static final String CANNOT_CREATE_RULE = "cannot.create.rule.checkout.outbound";
protected NodeService nodeService;
protected RuleService ruleService;

View File

@@ -0,0 +1,66 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api;
import java.util.List;
import org.alfresco.rest.api.model.rules.RuleSet;
import org.alfresco.rest.api.model.rules.RuleSetLink;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.service.Experimental;
/**
* Rule sets API.
*/
@Experimental
public interface RuleSets
{
/**
* Get rule sets for a folder.
*
* @param folderNodeId Folder node ID
* @param paging {@link Paging} information
* @param includes List of fields to include in the rule set
* @return {@link CollectionWithPagingInfo} containing a list page of rule sets
*/
CollectionWithPagingInfo<RuleSet> getRuleSets(String folderNodeId, List<String> includes, Paging paging);
/**
* Get the rule set with the given ID and check associations with the folder node.
*
* @param folderNodeId Folder node ID
* @param ruleSetId Rule set ID
* @param includes List of fields to include in the rule set
* @return {@link RuleSet} definition
*/
RuleSet getRuleSetById(String folderNodeId, String ruleSetId, List<String> includes);
/**
* Link a rule set to a folder
*/
RuleSetLink linkToRuleSet(String folderNodeId, String linkToNodeId);
}

View File

@@ -0,0 +1,54 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api;
import org.alfresco.rest.api.model.rules.RuleSetting;
import org.alfresco.service.Experimental;
/**
* Rule settings API.
*/
@Experimental
public interface RuleSettings
{
/**
* Get the rule setting with the given key.
*
* @param folderId Folder node ID
* @param ruleSettingKey Rule setting key
* @return {@link RuleSetting} The retrieved rule setting object.
*/
RuleSetting getRuleSetting(String folderId, String ruleSettingKey);
/**
* Set the rule setting against the specified folder.
*
* @param folderId The folder to update.
* @param ruleSetting The new rule setting.
* @return The updated rule setting object.
*/
RuleSetting setRuleSetting(String folderId, RuleSetting ruleSetting);
}

View File

@@ -26,10 +26,14 @@
package org.alfresco.rest.api;
import java.util.List;
import org.alfresco.rest.api.model.rules.Rule;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.rule.RuleServiceException;
/**
* Folder node rules API.
@@ -43,10 +47,11 @@ public interface Rules
*
* @param folderNodeId - folder node ID
* @param ruleSetId - rule set ID
* @param includes - The list of optional fields to include in the response.
* @param paging - {@link Paging} information
* @return {@link CollectionWithPagingInfo} containing a list page of folder rules
*/
CollectionWithPagingInfo<Rule> getRules(String folderNodeId, String ruleSetId, Paging paging);
CollectionWithPagingInfo<Rule> getRules(String folderNodeId, String ruleSetId, List<String> includes, Paging paging);
/**
* Get rule for rule's ID and check associations with folder node and rule set node
@@ -54,7 +59,42 @@ public interface Rules
* @param folderNodeId - folder node ID
* @param ruleSetId - rule set ID
* @param ruleId - rule ID
* @param includes - The list of optional fields to include in the response.
* @return {@link Rule} definition
*/
Rule getRuleById(String folderNodeId, String ruleSetId, String ruleId);
Rule getRuleById(String folderNodeId, String ruleSetId, String ruleId, List<String> includes);
/**
* Create new rules (and potentially a rule set if "_default_" is supplied).
*
* @param folderNodeId The node id of a folder.
* @param ruleSetId The id of a rule set (or "_default_" to use/create the default rule set for the folder).
* @param rule The definition of the rule.
* @param includes The list of optional fields to include in the response.
* @return The newly created rules.
* @throws InvalidArgumentException If the nodes are not the expected types, or the rule set does not correspond to the folder.
* @throws RuleServiceException If the folder is already linked to another rule set.
*/
List<Rule> createRules(String folderNodeId, String ruleSetId, List<Rule> rule, List<String> includes);
/**
* Update a rule.
*
* @param folderNodeId The id of a folder.
* @param ruleSetId The id of a rule set within the folder (or "_default_" to use the default rule set for the folder).
* @param ruleId The rule id.
* @param rule The new version of the rule.
* @param includes The list of optional fields to include in the response.
* @return The newly updated rule.
*/
Rule updateRuleById(String folderNodeId, String ruleSetId, String ruleId, Rule rule, List<String> includes);
/**
* Delete rule for rule's ID and check associations with folder node and rule set node
*
* @param folderNodeId - folder node ID
* @param ruleSetId - rule set ID
* @param ruleId - rule ID *
*/
void deleteRuleById(String folderNodeId, String ruleSetId, String ruleId);
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2021 Alfresco Software Limited
* Copyright (C) 2005 - 2022 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -713,6 +713,7 @@ public class CustomModelsImpl implements CustomModels
try
{
NodeRef nodeRef = customModelService.createDownloadNode(modelName, withForm);
nodeService.setProperty(nodeRef, ContentModel.PROP_NAME, modelName + DownloadsImpl.DEFAULT_ARCHIVE_EXTENSION);
return new CustomModelDownload(nodeRef);
}
catch (Exception ex)

View File

@@ -0,0 +1,156 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.impl.rules;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.NotFoundException;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.action.ParameterizedItemDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryException;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.json.JSONArray;
import org.json.JSONException;
@Experimental
public class ActionParameterConverter
{
private final DictionaryService dictionaryService;
private final ActionService actionService;
private final NamespaceService namespaceService;
public ActionParameterConverter(DictionaryService dictionaryService, ActionService actionService,
NamespaceService namespaceService)
{
this.dictionaryService = dictionaryService;
this.actionService = actionService;
this.namespaceService = namespaceService;
}
Map<String, Serializable> getConvertedParams(Map<String, Serializable> params, String name)
{
final Map<String, Serializable> parameters = new HashMap<>(params.size());
final ParameterizedItemDefinition definition = actionService.getActionDefinition(name);
if (definition == null)
{
throw new NotFoundException(NotFoundException.DEFAULT_MESSAGE_ID, new String[]{name});
}
for (Map.Entry<String, Serializable> param : params.entrySet())
{
final ParameterDefinition paramDef = definition.getParameterDefintion(param.getKey());
if (paramDef == null && !definition.getAdhocPropertiesAllowed())
{
throw new InvalidArgumentException(InvalidArgumentException.DEFAULT_MESSAGE_ID, new String[]{param.getKey(), name});
}
if (paramDef != null)
{
final QName typeQName = paramDef.getType();
parameters.put(param.getKey(), convertValue(typeQName, param.getValue()));
} else
{
parameters.put(param.getKey(), param.getValue().toString());
}
}
return parameters;
}
public Serializable convertParamFromServiceModel(Serializable param)
{
if (param instanceof QName)
{
return ((QName) param).toPrefixString(namespaceService);
}
else if (param instanceof NodeRef) {
return ((NodeRef) param).getId();
}
else
{
return param;
}
}
private Serializable convertValue(QName typeQName, Object propertyValue) throws JSONException
{
Serializable value;
final DataTypeDefinition typeDef = dictionaryService.getDataType(typeQName);
if (typeDef == null)
{
throw new NotFoundException(NotFoundException.DEFAULT_MESSAGE_ID, new String[]{typeQName.toPrefixString()});
}
if (propertyValue instanceof JSONArray)
{
final String javaClassName = typeDef.getJavaClassName();
try
{
Class.forName(javaClassName);
} catch (ClassNotFoundException e)
{
throw new DictionaryException("Java class " + javaClassName + " of property type " + typeDef.getName() + " is invalid", e);
}
final int length = ((JSONArray) propertyValue).length();
final List<Serializable> list = new ArrayList<>(length);
for (int i = 0; i < length; i++)
{
list.add(convertValue(typeQName, ((JSONArray) propertyValue).get(i)));
}
value = (Serializable) list;
}
else
{
if (typeQName.equals(DataTypeDefinition.QNAME) && typeQName.toString().contains(":"))
{
value = QName.createQName(propertyValue.toString(), namespaceService);
}
else if (typeQName.isMatch(DataTypeDefinition.NODE_REF))
{
value = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, propertyValue.toString());
}
else
{
value = (Serializable) DefaultTypeConverter.INSTANCE.convert(dictionaryService.getDataType(typeQName), propertyValue);
}
}
return value;
}
}

View File

@@ -0,0 +1,85 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.impl.rules;
import static org.alfresco.repo.web.scripts.rule.AbstractRuleWebScript.CANNOT_CREATE_RULE;
import static org.alfresco.service.cmr.rule.RuleType.OUTBOUND;
import java.util.Collections;
import java.util.List;
import org.alfresco.repo.action.CompositeActionImpl;
import org.alfresco.repo.action.RuntimeActionService;
import org.alfresco.repo.action.access.ActionAccessRestriction;
import org.alfresco.repo.action.executer.CheckOutActionExecuter;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.rule.Rule;
import org.apache.commons.collections.CollectionUtils;
@Experimental
public class ActionPermissionValidator
{
private final RuntimeActionService runtimeActionService;
public ActionPermissionValidator(RuntimeActionService runtimeActionService)
{
this.runtimeActionService = runtimeActionService;
}
Rule validateRulePermissions(Rule rule)
{
final List<Action> actions = ((CompositeActionImpl) rule.getAction()).getActions();
checkRestrictedAccessActions(actions);
checkRuleOutboundHasNoCheckOutAction(rule, actions);
return rule;
}
private void checkRestrictedAccessActions(List<Action> actions) {
actions.forEach(action -> {
ActionAccessRestriction.setActionContext(action, ActionAccessRestriction.RULE_ACTION_CONTEXT);
runtimeActionService.verifyActionAccessRestrictions(action);
});
}
private void checkRuleOutboundHasNoCheckOutAction(Rule rule, List<Action> actions) {
//TODO: rule types should never be empty in final implementation
if (CollectionUtils.isNotEmpty(rule.getRuleTypes()) && rule.getRuleTypes().contains(OUTBOUND))
{
for (Action action : actions)
{
if (action.getActionDefinitionName().equalsIgnoreCase(CheckOutActionExecuter.NAME))
{
throw new InvalidArgumentException(CANNOT_CREATE_RULE);
}
}
}
}
}

View File

@@ -23,95 +23,53 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api.impl.rules;
package org.alfresco.rest.api.impl;
import static org.alfresco.service.cmr.security.AccessStatus.ALLOWED;
import static org.alfresco.service.cmr.security.PermissionService.CHANGE_PERMISSIONS;
import java.util.Set;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.rule.RuleModel;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.Rules;
import org.alfresco.rest.api.model.rules.Rule;
import org.alfresco.rest.api.model.Node;
import org.alfresco.rest.api.model.rules.RuleSet;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.ListPage;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.rest.framework.core.exceptions.RelationshipResourceNotFoundException;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.rule.RuleService;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/** Responsible for validating nodes when working with rules. */
@Experimental
public class RulesImpl implements Rules
public class NodeValidator
{
private static final String RULE_SET_EXPECTED_TYPE_NAME = "rule set";
private Nodes nodes;
private PermissionService permissionService;
private RuleService ruleService;
@Override
public CollectionWithPagingInfo<Rule> getRules(final String folderNodeId, final String ruleSetId, final Paging paging)
{
final NodeRef folderNodeRef = validateFolderNode(folderNodeId);
validateRuleSetNode(ruleSetId, folderNodeRef);
final List<Rule> rules = ruleService.getRules(folderNodeRef).stream()
.map(Rule::from)
.collect(Collectors.toList());
return ListPage.of(rules, paging);
}
@Override
public Rule getRuleById(final String folderNodeId, final String ruleSetId, final String ruleId)
{
final NodeRef folderNodeRef = validateFolderNode(folderNodeId);
final NodeRef ruleSetNodeRef = validateRuleSetNode(ruleSetId, folderNodeRef);
final NodeRef ruleNodeRef = validateRuleNode(ruleId, ruleSetNodeRef);
return Rule.from(ruleService.getRule(ruleNodeRef));
}
public void setNodes(Nodes nodes)
{
this.nodes = nodes;
}
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
public void setRuleService(RuleService ruleService)
{
this.ruleService = ruleService;
}
private PermissionService permissionService;
private NodeService nodeService;
/**
* Validates if folder node exists and user have permission to read from it.
* Validates if folder node exists and the user has permission to use it.
*
* @param folderNodeId - folder node ID
* @param requireChangePermission - Whether to require change permission or just read permission.
* @return folder node reference
* @throws InvalidArgumentException if node is not of an expected type
* @throws PermissionDeniedException if user doesn't have right to read from folder
* @throws PermissionDeniedException if the user doesn't have the appropriate permission for the folder.
*/
private NodeRef validateFolderNode(final String folderNodeId)
public NodeRef validateFolderNode(final String folderNodeId, boolean requireChangePermission)
{
final NodeRef nodeRef = nodes.validateOrLookupNode(folderNodeId, null);
if (permissionService.hasReadPermission(nodeRef) != AccessStatus.ALLOWED) {
throw new PermissionDeniedException("Cannot read from this node!");
}
validatePermission(requireChangePermission, nodeRef);
verifyNodeType(nodeRef, ContentModel.TYPE_FOLDER, null);
return nodeRef;
@@ -125,21 +83,38 @@ public class RulesImpl implements Rules
* @return rule set node reference
* @throws InvalidArgumentException in case of not matching associated folder node
*/
private NodeRef validateRuleSetNode(final String ruleSetId, final NodeRef associatedFolderNodeRef)
public NodeRef validateRuleSetNode(final String ruleSetId, final NodeRef associatedFolderNodeRef)
{
if (RuleSet.isDefaultId(ruleSetId))
{
return ruleService.getRuleSetNode(associatedFolderNodeRef);
final NodeRef ruleSetNodeRef = ruleService.getRuleSetNode(associatedFolderNodeRef);
if (ruleSetNodeRef == null)
{
//folder doesn't have a -default- rule set
throw new RelationshipResourceNotFoundException(associatedFolderNodeRef.getId(), ruleSetId);
}
return ruleSetNodeRef;
}
final NodeRef ruleSetNodeRef = validateNode(ruleSetId, ContentModel.TYPE_SYSTEM_FOLDER, RULE_SET_EXPECTED_TYPE_NAME);
if (!ruleService.isRuleSetAssociatedWithFolder(ruleSetNodeRef, associatedFolderNodeRef)) {
if (!ruleService.isRuleSetAssociatedWithFolder(ruleSetNodeRef, associatedFolderNodeRef))
{
throw new InvalidArgumentException("Rule set is not associated with folder node!");
}
return ruleSetNodeRef;
}
public NodeRef validateRuleSetNode(String linkToNodeId, boolean requireChangePermission)
{
final Node ruleSetNode = nodes.getNode(linkToNodeId);
final ChildAssociationRef primaryParent = nodeService.getPrimaryParent(ruleSetNode.getNodeRef());
final NodeRef parentNode = primaryParent.getParentRef();
validatePermission(requireChangePermission, parentNode);
return parentNode;
}
/**
* Validates if rule node exists and associated rule set node matches.
*
@@ -148,7 +123,7 @@ public class RulesImpl implements Rules
* @return rule node reference
* @throws InvalidArgumentException in case of not matching associated rule set node
*/
private NodeRef validateRuleNode(final String ruleId, final NodeRef associatedRuleSetNodeRef)
public NodeRef validateRuleNode(final String ruleId, final NodeRef associatedRuleSetNodeRef)
{
final NodeRef ruleNodeRef = validateNode(ruleId, RuleModel.TYPE_RULE, null);
if (associatedRuleSetNodeRef != null && !ruleService.isRuleAssociatedWithRuleSet(ruleNodeRef, associatedRuleSetNodeRef))
@@ -167,11 +142,79 @@ public class RulesImpl implements Rules
return nodeRef;
}
private void verifyNodeType(final NodeRef nodeRef, final QName expectedType, final String expectedTypeName) {
private void validatePermission(boolean requireChangePermission, NodeRef nodeRef)
{
if (requireChangePermission)
{
if (permissionService.hasPermission(nodeRef, CHANGE_PERMISSIONS) != ALLOWED)
{
throw new PermissionDeniedException("Insufficient permissions to manage rules.");
}
}
else
{
if (permissionService.hasReadPermission(nodeRef) != ALLOWED)
{
throw new PermissionDeniedException("Cannot read from this node!");
}
}
}
private void verifyNodeType(final NodeRef nodeRef, final QName expectedType, final String expectedTypeName)
{
final Set<QName> expectedTypes = Set.of(expectedType);
if (!nodes.nodeMatches(nodeRef, expectedTypes, null)) {
final String expectedTypeLocalName = (expectedTypeName != null)? expectedTypeName : expectedType.getLocalName();
if (!nodes.nodeMatches(nodeRef, expectedTypes, null))
{
final String expectedTypeLocalName = (expectedTypeName != null) ? expectedTypeName : expectedType.getLocalName();
throw new InvalidArgumentException(String.format("NodeId of a %s is expected!", expectedTypeLocalName));
}
}
public boolean isRuleSetNode(String nodeId) {
try
{
validateNode(nodeId, ContentModel.TYPE_SYSTEM_FOLDER, RULE_SET_EXPECTED_TYPE_NAME);
return true;
} catch (InvalidArgumentException e) {
return false;
}
}
public boolean isRuleSetNotNullAndShared(final NodeRef ruleSetNodeRef, final NodeRef folderNodeRef)
{
if (ruleSetNodeRef == null && folderNodeRef != null)
{
final NodeRef ruleSetNode = ruleService.getRuleSetNode(folderNodeRef);
return ruleSetNode != null && ruleService.isRuleSetShared(ruleSetNode);
}
else
{
return isRuleSetNotNullAndShared(ruleSetNodeRef);
}
}
public boolean isRuleSetNotNullAndShared(final NodeRef ruleSetNodeRef)
{
return ruleSetNodeRef != null && ruleService.isRuleSetShared(ruleSetNodeRef);
}
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
public void setRuleService(RuleService ruleService)
{
this.ruleService = ruleService;
}
public void setNodes(Nodes nodes)
{
this.nodes = nodes;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
}

View File

@@ -0,0 +1,64 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.impl.rules;
import java.util.List;
import org.alfresco.rest.api.model.rules.Rule;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.rule.RuleService;
/** Responsible for creating {@link Rule} objects. */
@Experimental
public class RuleLoader
{
public static final String IS_SHARED = "isShared";
private RuleService ruleService;
private NodeValidator nodeValidator;
public Rule loadRule(org.alfresco.service.cmr.rule.Rule ruleModel, List<String> includes)
{
Rule rule = Rule.from(ruleModel);
if (includes != null && includes.contains(IS_SHARED))
{
NodeRef ruleSet = ruleService.getRuleSetNode(ruleModel.getNodeRef());
boolean isShared = nodeValidator.isRuleSetNotNullAndShared(ruleSet);
rule.setIsShared(isShared);
}
return rule;
}
public void setRuleService(RuleService ruleService)
{
this.ruleService = ruleService;
}
public void setNodeValidator(NodeValidator nodeValidator)
{
this.nodeValidator = nodeValidator;
}
}

View File

@@ -0,0 +1,90 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.impl.rules;
import static org.alfresco.rest.api.model.rules.InclusionType.INHERITED;
import static org.alfresco.rest.api.model.rules.InclusionType.LINKED;
import static org.alfresco.rest.api.model.rules.InclusionType.OWNED;
import java.util.List;
import org.alfresco.rest.api.model.rules.RuleSet;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
/** Responsible for converting a NodeRef into a {@link RuleSet} object. */
@Experimental
public class RuleSetLoader
{
protected static final String OWNING_FOLDER = "owningFolder";
protected static final String INCLUSION_TYPE = "inclusionType";
private NodeService nodeService;
/**
* Load a rule set for the given node ref.
*
* @param ruleSetNodeRef The rule set node.
* @param includes A list of fields to include.
* @return The rule set object.
*/
public RuleSet loadRuleSet(NodeRef ruleSetNodeRef, NodeRef folderNodeRef, List<String> includes)
{
String ruleSetId = ruleSetNodeRef.getId();
RuleSet ruleSet = RuleSet.of(ruleSetId);
if (includes != null)
{
NodeRef parentRef = nodeService.getPrimaryParent(ruleSetNodeRef).getParentRef();
if (includes.contains(OWNING_FOLDER))
{
ruleSet.setOwningFolder(parentRef);
}
if (includes.contains(INCLUSION_TYPE))
{
// In the case that a rule set applies to the given folder for multiple reasons then priority is given to owned, then linked, then inherited.
if (parentRef.equals(folderNodeRef))
{
ruleSet.setInclusionType(OWNED);
}
else
{
boolean linked = nodeService.getParentAssocs(ruleSetNodeRef)
.stream().map(ChildAssociationRef::getParentRef)
.anyMatch(folderNodeRef::equals);
ruleSet.setInclusionType(linked ? LINKED : INHERITED);
}
}
}
return ruleSet;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
}

View File

@@ -0,0 +1,134 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.impl.rules;
import static java.util.stream.Collectors.toList;
import java.util.List;
import java.util.Optional;
import org.alfresco.repo.rule.RuleModel;
import org.alfresco.repo.rule.RuntimeRuleService;
import org.alfresco.rest.api.RuleSets;
import org.alfresco.rest.api.model.rules.RuleSet;
import org.alfresco.rest.api.model.rules.RuleSetLink;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.ListPage;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.rule.RuleService;
@Experimental
public class RuleSetsImpl implements RuleSets
{
private RuleSetLoader ruleSetLoader;
private RuleService ruleService;
private NodeValidator validator;
private NodeService nodeService;
private RuntimeRuleService runtimeRuleService;
@Override
public CollectionWithPagingInfo<RuleSet> getRuleSets(String folderNodeId, List<String> includes, Paging paging)
{
NodeRef folderNode = validator.validateFolderNode(folderNodeId, false);
NodeRef ruleSetNode = ruleService.getRuleSetNode(folderNode);
List<RuleSet> ruleSets = Optional.ofNullable(ruleSetNode)
.map(nodeRef -> ruleSetLoader.loadRuleSet(nodeRef, folderNode, includes))
.stream().collect(toList());
return ListPage.of(ruleSets, paging);
}
@Override
public RuleSet getRuleSetById(String folderNodeId, String ruleSetId, List<String> includes)
{
NodeRef folderNode = validator.validateFolderNode(folderNodeId, false);
NodeRef ruleSetNode = validator.validateRuleSetNode(ruleSetId, folderNode);
return ruleSetLoader.loadRuleSet(ruleSetNode, folderNode, includes);
}
@Override
public RuleSetLink linkToRuleSet(String folderNodeId, String linkToNodeId)
{
final NodeRef folderNodeRef = validator.validateFolderNode(folderNodeId,true);
final boolean isRuleSetNode = validator.isRuleSetNode(linkToNodeId);
final NodeRef linkToNodeRef = isRuleSetNode
? validator.validateRuleSetNode(linkToNodeId, true)
: validator.validateFolderNode(linkToNodeId, true);
//The target node should have pre-existing rules to link to
if (!ruleService.hasRules(linkToNodeRef)) {
throw new InvalidArgumentException("The target node has no rules to link.");
}
//The folder shouldn't have any pre-existing rules
if (ruleService.hasRules(folderNodeRef)) {
throw new InvalidArgumentException("Unable to link to a ruleset because the folder has pre-existing rules or is already linked to a ruleset.");
}
// Create the destination folder as a secondary child of the first
NodeRef ruleSetNodeRef = runtimeRuleService.getSavedRuleFolderAssoc(linkToNodeRef).getChildRef();
// The required aspect will automatically be added to the node
nodeService.addChild(folderNodeRef, ruleSetNodeRef, RuleModel.ASSOC_RULE_FOLDER, RuleModel.ASSOC_RULE_FOLDER);
RuleSetLink ruleSetLink = new RuleSetLink();
ruleSetLink.setId(ruleSetNodeRef.getId());
return ruleSetLink;
}
public void setRuleSetLoader(RuleSetLoader ruleSetLoader)
{
this.ruleSetLoader = ruleSetLoader;
}
public void setValidator(NodeValidator validator)
{
this.validator = validator;
}
public void setRuleService(RuleService ruleService)
{
this.ruleService = ruleService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setRuntimeRuleService(RuntimeRuleService runtimeRuleService)
{
this.runtimeRuleService = runtimeRuleService;
}
}

View File

@@ -0,0 +1,107 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.impl.rules;
import static org.alfresco.repo.rule.RuleModel.ASPECT_IGNORE_INHERITED_RULES;
import static org.alfresco.rest.api.model.rules.RuleSetting.IS_INHERITANCE_ENABLED_KEY;
import java.util.Collections;
import org.alfresco.rest.api.RuleSettings;
import org.alfresco.rest.api.model.rules.RuleSetting;
import org.alfresco.rest.framework.core.exceptions.NotFoundException;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
@Experimental
public class RuleSettingsImpl implements RuleSettings
{
private NodeValidator validator;
private NodeService nodeService;
@Override
public RuleSetting getRuleSetting(String folderId, String ruleSettingKey)
{
NodeRef folderNode = validator.validateFolderNode(folderId, false);
switch (ruleSettingKey)
{
case IS_INHERITANCE_ENABLED_KEY:
return getIsInheritanceEnabled(folderNode);
default:
throw new NotFoundException("Unrecognised rule setting key " + ruleSettingKey);
}
}
private RuleSetting getIsInheritanceEnabled(NodeRef folderNode)
{
boolean inheritanceDisabled = nodeService.hasAspect(folderNode, ASPECT_IGNORE_INHERITED_RULES);
return RuleSetting.builder().key(IS_INHERITANCE_ENABLED_KEY).value(!inheritanceDisabled).create();
}
@Override
public RuleSetting setRuleSetting(String folderId, RuleSetting ruleSetting)
{
NodeRef folderNode = validator.validateFolderNode(folderId, true);
switch (ruleSetting.getKey())
{
case IS_INHERITANCE_ENABLED_KEY:
return updateIsInheritanceEnabled(folderNode, ruleSetting.getValue());
default:
throw new NotFoundException("Unrecognised rule setting key " + ruleSetting.getKey());
}
}
private RuleSetting updateIsInheritanceEnabled(NodeRef folderNode, Object value)
{
if (!(value instanceof Boolean))
{
throw new IllegalArgumentException("Rule setting " + IS_INHERITANCE_ENABLED_KEY + " requires a boolean value.");
}
if ((boolean) value)
{
nodeService.removeAspect(folderNode, ASPECT_IGNORE_INHERITED_RULES);
}
else
{
nodeService.addAspect(folderNode, ASPECT_IGNORE_INHERITED_RULES, Collections.emptyMap());
}
return RuleSetting.builder().key(IS_INHERITANCE_ENABLED_KEY).value(value).create();
}
public void setValidator(NodeValidator validator)
{
this.validator = validator;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
}

View File

@@ -0,0 +1,177 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.impl.rules;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.Rules;
import org.alfresco.rest.api.model.rules.Rule;
import org.alfresco.rest.api.model.rules.RuleSet;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.ListPage;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.action.CompositeAction;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.rule.RuleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Experimental
public class RulesImpl implements Rules
{
private static final Logger LOGGER = LoggerFactory.getLogger(RulesImpl.class);
private Nodes nodes;
private RuleService ruleService;
private NodeValidator validator;
private RuleLoader ruleLoader;
private ActionParameterConverter actionParameterConverter;
private ActionPermissionValidator actionPermissionValidator;
@Override
public CollectionWithPagingInfo<Rule> getRules(final String folderNodeId,
final String ruleSetId,
final List<String> includes,
final Paging paging)
{
final NodeRef folderNodeRef = validator.validateFolderNode(folderNodeId, false);
validator.validateRuleSetNode(ruleSetId, folderNodeRef);
final List<Rule> rules = ruleService.getRules(folderNodeRef).stream()
.map(ruleModel -> loadRuleAndConvertActionParams(ruleModel, includes))
.collect(Collectors.toList());
return ListPage.of(rules, paging);
}
@Override
public Rule getRuleById(final String folderNodeId, final String ruleSetId, final String ruleId, final List<String> includes)
{
final NodeRef folderNodeRef = validator.validateFolderNode(folderNodeId, false);
final NodeRef ruleSetNodeRef = validator.validateRuleSetNode(ruleSetId, folderNodeRef);
final NodeRef ruleNodeRef = validator.validateRuleNode(ruleId, ruleSetNodeRef);
return loadRuleAndConvertActionParams(ruleService.getRule(ruleNodeRef), includes);
}
@Override
public List<Rule> createRules(final String folderNodeId, final String ruleSetId, final List<Rule> rules, final List<String> includes)
{
final NodeRef folderNodeRef = validator.validateFolderNode(folderNodeId, true);
// Don't validate the ruleset node if -default- is passed since we may need to create it.
if (RuleSet.isNotDefaultId(ruleSetId))
{
validator.validateRuleSetNode(ruleSetId, folderNodeRef);
}
return rules.stream()
.map(this::mapToServiceModelAndValidateActions)
.map(rule -> ruleService.saveRule(folderNodeRef, rule))
.map(rule -> loadRuleAndConvertActionParams(rule, includes))
.collect(Collectors.toList());
}
@Override
public Rule updateRuleById(String folderNodeId, String ruleSetId, String ruleId, Rule rule, List<String> includes)
{
LOGGER.debug("Updating rule in folder {}, rule set {}, rule {} to {}", folderNodeId, ruleSetId, ruleId, rule);
NodeRef folderNodeRef = validator.validateFolderNode(folderNodeId, true);
NodeRef ruleSetNodeRef = validator.validateRuleSetNode(ruleSetId, folderNodeRef);
validator.validateRuleNode(ruleId, ruleSetNodeRef);
return ruleLoader.loadRule(ruleService.saveRule(folderNodeRef, mapToServiceModelAndValidateActions(rule)), includes);
}
@Override
public void deleteRuleById(String folderNodeId, String ruleSetId, String ruleId)
{
final NodeRef folderNodeRef = validator.validateFolderNode(folderNodeId, true);
final NodeRef ruleSetNodeRef = validator.validateRuleSetNode(ruleSetId, folderNodeRef);
final NodeRef ruleNodeRef = validator.validateRuleNode(ruleId, ruleSetNodeRef);
final org.alfresco.service.cmr.rule.Rule rule = ruleService.getRule(ruleNodeRef);
ruleService.removeRule(folderNodeRef, rule);
}
private org.alfresco.service.cmr.rule.Rule mapToServiceModelAndValidateActions(Rule rule)
{
final org.alfresco.service.cmr.rule.Rule serviceModelRule = rule.toServiceModel(nodes);
final CompositeAction compositeAction = (CompositeAction) serviceModelRule.getAction();
compositeAction.getActions().forEach(action -> action.setParameterValues(
actionParameterConverter.getConvertedParams(action.getParameterValues(), action.getActionDefinitionName())));
return actionPermissionValidator.validateRulePermissions(serviceModelRule);
}
private Rule loadRuleAndConvertActionParams(org.alfresco.service.cmr.rule.Rule ruleModel, List<String> includes)
{
final Rule rule = ruleLoader.loadRule(ruleModel, includes);
rule.getActions()
.forEach(a -> a.setParams(a.getParams().entrySet()
.stream()
.collect(Collectors
.toMap(Map.Entry::getKey, e -> actionParameterConverter.convertParamFromServiceModel(e.getValue())))
)
);
return rule;
}
public void setNodes(Nodes nodes)
{
this.nodes = nodes;
}
public void setRuleService(RuleService ruleService)
{
this.ruleService = ruleService;
}
public void setValidator(NodeValidator validator)
{
this.validator = validator;
}
public void setRuleLoader(RuleLoader ruleLoader)
{
this.ruleLoader = ruleLoader;
}
public void setActionParameterConverter(ActionParameterConverter actionParameterConverter)
{
this.actionParameterConverter = actionParameterConverter;
}
public void setActionPermissionValidator(ActionPermissionValidator actionPermissionValidator)
{
this.actionPermissionValidator = actionPermissionValidator;
}
}

View File

@@ -0,0 +1,169 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.model.rules;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.repo.action.CompositeActionImpl;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.util.GUID;
@Experimental
public class Action
{
private String actionDefinitionId;
private Map<String, Serializable> params;
/**
* Converts service POJO action to REST model action.
*
* @param actionModel - {@link org.alfresco.service.cmr.action.Action} service POJO
* @return {@link Action} REST model
*/
public static Action from(final org.alfresco.service.cmr.action.Action actionModel)
{
if (actionModel == null)
{
return null;
}
final Action.Builder builder = builder().actionDefinitionId(actionModel.getActionDefinitionName());
if (actionModel.getParameterValues() != null)
{
builder.params(new HashMap<>(actionModel.getParameterValues()));
}
return builder.create();
}
/**
* Convert the REST model object to the equivalent service POJO.
*
* @param nodeRef The node reference.
* @return The action service POJO.
*/
public org.alfresco.service.cmr.action.Action toServiceModel(final NodeRef nodeRef)
{
return new ActionImpl(nodeRef, GUID.generate(), this.actionDefinitionId, params);
}
/**
* Convert the REST model objects to composite action service POJO.
*
* @param actions List of actions.
* @return The composite action service POJO.
*/
public static org.alfresco.service.cmr.action.Action toCompositeAction(final List<Action> actions) {
if (actions == null)
{
return null;
}
final org.alfresco.service.cmr.action.CompositeAction compositeAction = new CompositeActionImpl(null, GUID.generate());
actions.forEach(action -> compositeAction.addAction(action.toServiceModel(null)));
return compositeAction;
}
public String getActionDefinitionId()
{
return actionDefinitionId;
}
public void setActionDefinitionId(String actionDefinitionId)
{
this.actionDefinitionId = actionDefinitionId;
}
public Map<String, Serializable> getParams()
{
return params;
}
public void setParams(Map<String, Serializable> params)
{
this.params = params;
}
@Override
public String toString()
{
return "Action{" + "actionDefinitionId='" + actionDefinitionId + '\'' + ", params=" + params + '}';
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Action action = (Action) o;
return Objects.equals(actionDefinitionId, action.actionDefinitionId) && Objects.equals(params, action.params);
}
@Override
public int hashCode()
{
return Objects.hash(actionDefinitionId, params);
}
public static Builder builder()
{
return new Builder();
}
public static class Builder
{
private String actionDefinitionId;
private Map<String, Serializable> params;
public Builder actionDefinitionId(String actionDefinitionId)
{
this.actionDefinitionId = actionDefinitionId;
return this;
}
public Builder params(Map<String, Serializable> params)
{
this.params = params;
return this;
}
public Action create() {
final Action action = new Action();
action.setActionDefinitionId(actionDefinitionId);
action.setParams(params);
return action;
}
}
}

View File

@@ -0,0 +1,230 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.model.rules;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.action.ActionCondition;
import org.apache.commons.collections.CollectionUtils;
@Experimental
public class CompositeCondition
{
private boolean inverted;
private ConditionOperator booleanMode = ConditionOperator.AND;
private List<CompositeCondition> compositeConditions;
private List<SimpleCondition> simpleConditions;
/**
* Converts Action conditions (service POJO) list to composite condition (REST model).
*
* @param actionConditions - list of {@link ActionCondition} service POJOs
* @return {@link CompositeCondition} REST model
*/
public static CompositeCondition from(final List<ActionCondition> actionConditions)
{
if (actionConditions == null)
{
return null;
}
final CompositeCondition conditions = new CompositeCondition();
conditions.compositeConditions = new ArrayList<>();
// group action conditions by inversion flag
actionConditions.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(ActionCondition::getInvertCondition))
// map action condition sub lists
.forEach((inverted, actionConditionsPart) -> Optional.ofNullable(CompositeCondition.ofActionConditions(actionConditionsPart, inverted, ConditionOperator.AND))
// if composite condition present add to final list
.ifPresent(compositeCondition -> conditions.compositeConditions.add(compositeCondition)));
if (conditions.compositeConditions.isEmpty()) {
conditions.compositeConditions = null;
}
return conditions;
}
private static CompositeCondition ofActionConditions(final List<ActionCondition> actionConditions, final boolean inverted, final ConditionOperator conditionOperator)
{
if (actionConditions == null)
{
return null;
}
return ofSimpleConditions(SimpleCondition.listOf(actionConditions), inverted, conditionOperator);
}
/**
* Creates a composite condition instance of simple conditions.
*
* @param simpleConditions - list of {@link SimpleCondition}
* @param inverted - determines if condition should be inverted
* @param conditionOperator - determines the operation, see {@link ConditionOperator}
* @return {@link CompositeCondition}
*/
public static CompositeCondition ofSimpleConditions(final List<SimpleCondition> simpleConditions, final boolean inverted, final ConditionOperator conditionOperator)
{
return of(simpleConditions, null, inverted, conditionOperator);
}
private static CompositeCondition of(final List<SimpleCondition> simpleConditions, final List<CompositeCondition> compositeConditions,
final boolean inverted, final ConditionOperator conditionOperator)
{
if (CollectionUtils.isEmpty(simpleConditions) && CollectionUtils.isEmpty(compositeConditions))
{
return null;
}
return builder()
.inverted(inverted)
.booleanMode(conditionOperator)
.simpleConditions(simpleConditions)
.compositeConditions(compositeConditions)
.create();
}
public boolean isInverted()
{
return inverted;
}
public void setInverted(boolean inverted)
{
this.inverted = inverted;
}
public String getBooleanMode()
{
if (booleanMode == null)
{
return null;
}
return booleanMode.name().toLowerCase();
}
public void setBooleanMode(ConditionOperator booleanMode)
{
this.booleanMode = booleanMode;
}
public List<CompositeCondition> getCompositeConditions()
{
return compositeConditions;
}
public void setCompositeConditions(List<CompositeCondition> compositeConditions)
{
this.compositeConditions = compositeConditions;
}
public List<SimpleCondition> getSimpleConditions()
{
return simpleConditions;
}
public void setSimpleConditions(List<SimpleCondition> simpleConditions)
{
this.simpleConditions = simpleConditions;
}
@Override
public String toString()
{
return "CompositeCondition{" + "inverted=" + inverted + ", booleanMode=" + booleanMode + ", compositeConditions=" + compositeConditions + ", simpleConditions="
+ simpleConditions + '}';
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
CompositeCondition that = (CompositeCondition) o;
return inverted == that.inverted && booleanMode == that.booleanMode && Objects.equals(compositeConditions, that.compositeConditions) && Objects.equals(
simpleConditions, that.simpleConditions);
}
@Override
public int hashCode()
{
return Objects.hash(inverted, booleanMode, compositeConditions, simpleConditions);
}
public static Builder builder()
{
return new Builder();
}
public static class Builder
{
private boolean inverted;
private ConditionOperator booleanMode = ConditionOperator.AND;
private List<CompositeCondition> compositeConditions;
private List<SimpleCondition> simpleConditions;
public Builder inverted(boolean inverted)
{
this.inverted = inverted;
return this;
}
public Builder booleanMode(ConditionOperator booleanMode)
{
this.booleanMode = booleanMode;
return this;
}
public Builder compositeConditions(List<CompositeCondition> compositeConditions)
{
this.compositeConditions = compositeConditions;
return this;
}
public Builder simpleConditions(List<SimpleCondition> simpleConditions)
{
this.simpleConditions = simpleConditions;
return this;
}
public CompositeCondition create()
{
final CompositeCondition condition = new CompositeCondition();
condition.setInverted(inverted);
condition.setBooleanMode(booleanMode);
condition.setCompositeConditions(compositeConditions);
condition.setSimpleConditions(simpleConditions);
return condition;
}
}
}

View File

@@ -0,0 +1,35 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.model.rules;
import org.alfresco.service.Experimental;
@Experimental
public enum ConditionOperator
{
AND, OR
}

View File

@@ -0,0 +1,59 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.model.rules;
import com.fasterxml.jackson.annotation.JsonValue;
import org.alfresco.service.Experimental;
/** The reason why a rule set applies to a folder. */
@Experimental
public enum InclusionType
{
OWNED, INHERITED, LINKED;
/**
* Load an InclusionType from a given string (case insensitively).
*
* @param inclusionType The given string.
* @return The inclusion type.
*/
public static InclusionType from(String inclusionType)
{
return InclusionType.valueOf(inclusionType.toUpperCase());
}
/**
* The lower case version of the inclusion type.
*
* @return A lowercase string.
*/
@JsonValue
public String toString()
{
return super.toString().toLowerCase();
}
}

View File

@@ -26,30 +26,106 @@
package org.alfresco.rest.api.model.rules;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.repo.action.executer.ScriptActionExecuter;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.framework.resource.UniqueId;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.action.CompositeAction;
import java.util.List;
import java.util.stream.Collectors;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.util.GUID;
@Experimental
public class Rule
{
private String id;
private String name;
private String description;
private boolean enabled;
private boolean cascade;
private boolean asynchronous;
private Boolean isShared;
private String errorScript;
private List<RuleTrigger> triggers = List.of(RuleTrigger.INBOUND);
private CompositeCondition conditions;
private List<Action> actions;
public static Rule from(final org.alfresco.service.cmr.rule.Rule ruleModel) {
if (ruleModel == null) {
/**
* Converts service POJO rule to REST model rule.
*
* @param ruleModel - {@link org.alfresco.service.cmr.rule.Rule} service POJO
* @return {@link Rule} REST model
*/
public static Rule from(final org.alfresco.service.cmr.rule.Rule ruleModel)
{
if (ruleModel == null)
{
return null;
}
final Rule rule = new Rule();
rule.id = ruleModel.getNodeRef().getId();
rule.name = ruleModel.getTitle();
final Rule.Builder builder = builder()
.name(ruleModel.getTitle())
.description(ruleModel.getDescription())
.enabled(!ruleModel.getRuleDisabled())
.cascade(ruleModel.isAppliedToChildren())
.asynchronous(ruleModel.getExecuteAsynchronously());
return rule;
if (ruleModel.getNodeRef() != null) {
builder.id(ruleModel.getNodeRef().getId());
}
if (ruleModel.getRuleTypes() != null)
{
builder.triggers(ruleModel.getRuleTypes().stream().map(RuleTrigger::of).collect(Collectors.toList()));
}
if (ruleModel.getAction() != null)
{
builder.conditions(CompositeCondition.from(ruleModel.getAction().getActionConditions()));
if (ruleModel.getAction().getCompensatingAction() != null && ruleModel.getAction().getCompensatingAction().getParameterValue(ScriptActionExecuter.PARAM_SCRIPTREF) != null)
{
builder.errorScript(ruleModel.getAction().getCompensatingAction().getParameterValue(ScriptActionExecuter.PARAM_SCRIPTREF).toString());
}
if (ruleModel.getAction() instanceof CompositeAction && ((CompositeAction) ruleModel.getAction()).getActions() != null)
{
builder.actions(((CompositeAction) ruleModel.getAction()).getActions().stream().map(Action::from).collect(Collectors.toList()));
}
}
return builder.create();
}
/**
* Convert the REST model object to the equivalent service POJO.
*
* @param nodes The nodes API.
* @return The rule service POJO.
*/
public org.alfresco.service.cmr.rule.Rule toServiceModel(Nodes nodes)
{
final org.alfresco.service.cmr.rule.Rule ruleModel = new org.alfresco.service.cmr.rule.Rule();
final NodeRef nodeRef = (id != null) ? nodes.validateOrLookupNode(id, null) : null;
ruleModel.setNodeRef(nodeRef);
ruleModel.setTitle(name);
ruleModel.setDescription(description);
ruleModel.setRuleDisabled(!enabled);
ruleModel.applyToChildren(cascade);
ruleModel.setExecuteAsynchronously(asynchronous);
if (triggers != null)
{
ruleModel.setRuleTypes(triggers.stream().map(RuleTrigger::getValue).collect(Collectors.toList()));
}
ruleModel.setAction(Action.toCompositeAction(actions));
if (errorScript != null)
{
final org.alfresco.service.cmr.action.Action compensatingAction = new ActionImpl(null, GUID.generate(), ScriptActionExecuter.NAME);
compensatingAction.setParameterValue(ScriptActionExecuter.PARAM_SCRIPTREF, errorScript);
ruleModel.getAction().setCompensatingAction(compensatingAction);
}
return ruleModel;
}
@UniqueId
@@ -73,9 +149,244 @@ public class Rule
this.name = name;
}
public String getDescription()
{
return description;
}
public void setDescription(String description)
{
this.description = description;
}
public boolean isEnabled()
{
return enabled;
}
public void setEnabled(boolean enabled)
{
this.enabled = enabled;
}
public boolean isCascade()
{
return cascade;
}
public void setCascade(boolean cascade)
{
this.cascade = cascade;
}
public boolean isAsynchronous()
{
return asynchronous;
}
public void setAsynchronous(boolean asynchronous)
{
this.asynchronous = asynchronous;
}
public String getErrorScript()
{
return errorScript;
}
public void setErrorScript(String errorScript)
{
this.errorScript = errorScript;
}
public Boolean isIsShared()
{
return isShared;
}
public void setIsShared(Boolean shared)
{
this.isShared = shared;
}
public List<String> getTriggers()
{
if (triggers == null)
{
return null;
}
return triggers.stream().map(RuleTrigger::getValue).collect(Collectors.toList());
}
public void setTriggers(List<String> triggers)
{
if (triggers != null)
{
this.triggers = triggers.stream().map(RuleTrigger::of).collect(Collectors.toList());
}
}
public void setRuleTriggers(List<RuleTrigger> triggers)
{
this.triggers = triggers;
}
public CompositeCondition getConditions()
{
return conditions;
}
public void setConditions(CompositeCondition conditions)
{
this.conditions = conditions;
}
public List<Action> getActions()
{
return actions;
}
public void setActions(List<Action> actions)
{
this.actions = actions;
}
@Override
public String toString()
{
return "Rule{" + "id='" + id + '\'' + ", name='" + name + '\'' + '}';
return "Rule{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", description='" + description + '\'' + ", enabled=" + enabled + ", cascade=" + cascade
+ ", asynchronous=" + asynchronous + ", isShared=" + isShared + ", errorScript='" + errorScript + '\'' + ", triggers=" + triggers + ", conditions=" + conditions
+ ", actions=" + actions + '}';
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Rule rule = (Rule) o;
return enabled == rule.enabled
&& cascade == rule.cascade
&& asynchronous == rule.asynchronous
&& Objects.equals(isShared, rule.isShared)
&& Objects.equals(id, rule.id)
&& Objects.equals(name, rule.name)
&& Objects.equals(description, rule.description)
&& Objects.equals(errorScript, rule.errorScript)
&& Objects.equals(triggers, rule.triggers)
&& Objects.equals(conditions, rule.conditions)
&& Objects.equals(actions, rule.actions);
}
@Override
public int hashCode()
{
return Objects.hash(id, name, description, enabled, cascade, asynchronous, isShared, errorScript, triggers, conditions, actions);
}
public static Builder builder()
{
return new Builder();
}
/** Builder class. */
public static class Builder
{
private String id;
private String name;
private String description;
private boolean enabled;
private boolean cascade;
private boolean asynchronous;
private Boolean isShared;
private String errorScript;
private List<RuleTrigger> triggers = List.of(RuleTrigger.INBOUND);
private CompositeCondition conditions;
private List<Action> actions;
public Builder id(String id)
{
this.id = id;
return this;
}
public Builder name(String name)
{
this.name = name;
return this;
}
public Builder description(String description)
{
this.description = description;
return this;
}
public Builder enabled(boolean enabled)
{
this.enabled = enabled;
return this;
}
public Builder cascade(boolean cascade)
{
this.cascade = cascade;
return this;
}
public Builder asynchronous(boolean asynchronous)
{
this.asynchronous = asynchronous;
return this;
}
public Builder isShared(Boolean isShared)
{
this.isShared = isShared;
return this;
}
public Builder errorScript(String errorScript)
{
this.errorScript = errorScript;
return this;
}
public Builder triggers(List<RuleTrigger> triggers)
{
this.triggers = triggers;
return this;
}
public Builder conditions(CompositeCondition conditions)
{
this.conditions = conditions;
return this;
}
public Builder actions(List<Action> actions)
{
this.actions = actions;
return this;
}
public Rule create()
{
Rule rule = new Rule();
rule.setId(id);
rule.setName(name);
rule.setDescription(description);
rule.setEnabled(enabled);
rule.setCascade(cascade);
rule.setAsynchronous(asynchronous);
rule.setIsShared(isShared);
rule.setErrorScript(errorScript);
rule.setRuleTriggers(triggers);
rule.setConditions(conditions);
rule.setActions(actions);
return rule;
}
}
}

View File

@@ -26,29 +26,26 @@
package org.alfresco.rest.api.model.rules;
import java.util.Objects;
import java.util.StringJoiner;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.repository.NodeRef;
@Experimental
public class RuleSet
{
private static final String DEFAULT_ID = "-default-";
public static final String DEFAULT_ID = "-default-";
private String id;
private NodeRef owningFolder;
private InclusionType inclusionType;
public static RuleSet of(String id)
{
final RuleSet ruleSet = new RuleSet();
ruleSet.id = id;
return ruleSet;
}
public boolean isNotDefaultId() {
return isNotDefaultId(this.id);
}
public boolean isDefaultId() {
return isDefaultId(this.id);
return builder()
.id(id)
.create();
}
public static boolean isNotDefaultId(final String id) {
@@ -69,9 +66,93 @@ public class RuleSet
this.id = id;
}
public NodeRef getOwningFolder()
{
return owningFolder;
}
public void setOwningFolder(NodeRef owningFolder)
{
this.owningFolder = owningFolder;
}
public InclusionType getInclusionType()
{
return inclusionType;
}
public void setInclusionType(InclusionType inclusionType)
{
this.inclusionType = inclusionType;
}
@Override
public String toString()
{
return "RuleSet{" + "id='" + id + '\'' + '}';
return "RuleSet{"
+ new StringJoiner(", ")
.add("id='" + id + "'")
.add("owningFolder='" + owningFolder + "'")
.add("inclusionType='" + inclusionType + "'")
.toString()
+ '}';
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
RuleSet ruleSet = (RuleSet) o;
return Objects.equals(id, ruleSet.id)
&& Objects.equals(owningFolder, ruleSet.owningFolder)
&& inclusionType == ruleSet.inclusionType;
}
@Override
public int hashCode()
{
return Objects.hash(id, owningFolder, inclusionType);
}
public static Builder builder()
{
return new Builder();
}
public static class Builder
{
private String id;
private NodeRef owningFolder;
private InclusionType inclusionType;
public Builder id(String id)
{
this.id = id;
return this;
}
public Builder owningFolder(NodeRef owningFolder)
{
this.owningFolder = owningFolder;
return this;
}
public Builder inclusionType(InclusionType inclusionType)
{
this.inclusionType = inclusionType;
return this;
}
public RuleSet create()
{
final RuleSet ruleSet = new RuleSet();
ruleSet.setId(id);
ruleSet.setOwningFolder(owningFolder);
ruleSet.setInclusionType(inclusionType);
return ruleSet;
}
}
}

View File

@@ -0,0 +1,46 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.model.rules;
public class RuleSetLink
{
/**
* This id is referring to the node id of the linked-to-folder which contains the ruleset(s)
*/
private String id;
public void setId(String id)
{
this.id = id;
}
public String getId()
{
return id;
}
}

View File

@@ -0,0 +1,126 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.model.rules;
import java.util.Objects;
import java.util.StringJoiner;
import org.alfresco.rest.framework.resource.UniqueId;
import org.alfresco.service.Experimental;
@Experimental
public class RuleSetting
{
public static final String IS_INHERITANCE_ENABLED_KEY = "-isInheritanceEnabled-";
private String key;
private Object value;
@UniqueId
public String getKey()
{
return key;
}
public void setKey(String key)
{
this.key = key;
}
public Object getValue()
{
return value;
}
public void setValue(Object value)
{
this.value = value;
}
@Override
public String toString()
{
return "RuleSetting{"
+ new StringJoiner(", ")
.add("key=" + key)
.add("value=" + value.toString())
.toString()
+ "}";
}
@Override
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (!(o instanceof RuleSetting))
{
return false;
}
RuleSetting that = (RuleSetting) o;
return Objects.equals(key, that.key)
&& Objects.equals(value, that.value);
}
@Override
public int hashCode()
{
return Objects.hash(key, value);
}
public static RuleSetting.Builder builder()
{
return new RuleSetting.Builder();
}
public static class Builder
{
private String key;
private Object value;
public RuleSetting.Builder key(String key)
{
this.key = key;
return this;
}
public RuleSetting.Builder value(Object value)
{
this.value = value;
return this;
}
public RuleSetting create()
{
final RuleSetting ruleSetting = new RuleSetting();
ruleSetting.setKey(key);
ruleSetting.setValue(value);
return ruleSetting;
}
}
}

View File

@@ -0,0 +1,45 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.model.rules;
import org.alfresco.service.Experimental;
@Experimental
public enum RuleTrigger
{
INBOUND, UPDATE, OUTBOUND;
public String getValue()
{
return this.name().toLowerCase();
}
public static RuleTrigger of(final String value)
{
return RuleTrigger.valueOf(value.toUpperCase());
}
}

View File

@@ -0,0 +1,277 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.model.rules;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.alfresco.repo.action.evaluator.CompareMimeTypeEvaluator;
import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator;
import org.alfresco.repo.action.evaluator.HasAspectEvaluator;
import org.alfresco.repo.action.evaluator.HasChildEvaluator;
import org.alfresco.repo.action.evaluator.HasTagEvaluator;
import org.alfresco.repo.action.evaluator.HasVersionHistoryEvaluator;
import org.alfresco.repo.action.evaluator.InCategoryEvaluator;
import org.alfresco.repo.action.evaluator.IsSubTypeEvaluator;
import org.alfresco.repo.action.evaluator.NoConditionEvaluator;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.action.ActionCondition;
import org.apache.commons.collections.CollectionUtils;
@Experimental
public class SimpleCondition
{
private static final String COMPARATOR_EQUALS = "equals";
private String field;
private String comparator;
private String parameter;
/**
* Converts list of service POJO action conditions to list of REST model simple conditions.
*
* @param actionConditions - list of {@link ActionCondition} service POJOs
* @return list of {@link SimpleCondition} REST models
*/
public static List<SimpleCondition> listOf(final List<ActionCondition> actionConditions)
{
if (CollectionUtils.isEmpty(actionConditions))
{
return null;
}
return actionConditions.stream()
.map(SimpleCondition::from)
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
/**
* Creates simple condition REST model instance from service POJO action condition.
*
* @param actionCondition - {@link ActionCondition} service POJO
* @return {@link SimpleCondition} REST model
*/
public static SimpleCondition from(final ActionCondition actionCondition)
{
if (actionCondition == null || actionCondition.getActionConditionDefinitionName() == null || actionCondition.getParameterValues() == null)
{
return null;
}
switch (actionCondition.getActionConditionDefinitionName())
{
case ComparePropertyValueEvaluator.NAME:
return createComparePropertyValueCondition(actionCondition);
case CompareMimeTypeEvaluator.NAME:
return createCompareMimeTypeCondition(actionCondition);
case HasAspectEvaluator.NAME:
return createHasAspectCondition(actionCondition);
case HasChildEvaluator.NAME:
return createHasChildCondition(actionCondition);
case HasTagEvaluator.NAME:
return createHasTagCondition(actionCondition);
case HasVersionHistoryEvaluator.NAME:
return createHasVersionHistoryCondition(actionCondition);
case InCategoryEvaluator.NAME:
return createInCategoryCondition(actionCondition);
case IsSubTypeEvaluator.NAME:
return createIsSubtypeCondition(actionCondition);
case NoConditionEvaluator.NAME:
default:
return null;
}
}
public String getField()
{
return field;
}
public void setField(String field)
{
this.field = field;
}
public String getComparator()
{
return comparator;
}
public void setComparator(String comparator)
{
this.comparator = comparator;
}
public String getParameter()
{
return parameter;
}
public void setParameter(String parameter)
{
this.parameter = parameter;
}
@Override
public String toString()
{
return "SimpleCondition{" + "field='" + field + '\'' + ", comparator='" + comparator + '\'' + ", parameter='" + parameter + '\'' + '}';
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
SimpleCondition that = (SimpleCondition) o;
return Objects.equals(field, that.field) && Objects.equals(comparator, that.comparator) && Objects.equals(parameter, that.parameter);
}
@Override
public int hashCode()
{
return Objects.hash(field, comparator, parameter);
}
private static SimpleCondition createComparePropertyValueCondition(final ActionCondition actionCondition) {
final SimpleCondition.Builder builder = builder();
if (actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_CONTENT_PROPERTY) != null)
{
builder.field(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_CONTENT_PROPERTY).toString().toLowerCase());
} else {
builder.field(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_PROPERTY).toString().toLowerCase());
}
return builder
.comparator(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_OPERATION).toString().toLowerCase())
.parameter(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_VALUE).toString())
.create();
}
private static SimpleCondition createCompareMimeTypeCondition(final ActionCondition actionCondition) {
return builder()
.field(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_PROPERTY).toString().toLowerCase())
.comparator(COMPARATOR_EQUALS)
.parameter(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_VALUE).toString())
.create();
}
private static SimpleCondition createHasAspectCondition(final ActionCondition actionCondition) {
return builder()
.field(HasAspectEvaluator.PARAM_ASPECT)
.comparator(COMPARATOR_EQUALS)
.parameter(actionCondition.getParameterValues().get(HasAspectEvaluator.PARAM_ASPECT).toString())
.create();
}
private static SimpleCondition createHasChildCondition(final ActionCondition actionCondition) {
final SimpleCondition.Builder builder = builder();
if (actionCondition.getParameterValues().get(HasChildEvaluator.PARAM_ASSOC_TYPE) != null)
{
builder.field(actionCondition.getParameterValues().get(HasChildEvaluator.PARAM_ASSOC_TYPE).toString().toLowerCase());
} else {
builder.field(actionCondition.getParameterValues().get(HasChildEvaluator.PARAM_ASSOC_NAME).toString().toLowerCase());
}
return builder
.comparator(COMPARATOR_EQUALS)
.parameter(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_VALUE).toString())
.create();
}
private static SimpleCondition createHasTagCondition(final ActionCondition actionCondition) {
return builder()
.field(HasTagEvaluator.PARAM_TAG)
.comparator(COMPARATOR_EQUALS)
.parameter(actionCondition.getParameterValues().get(HasTagEvaluator.PARAM_TAG).toString())
.create();
}
private static SimpleCondition createHasVersionHistoryCondition(final ActionCondition actionCondition) {
return builder()
.field(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_PROPERTY).toString().toLowerCase())
.comparator(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_OPERATION).toString().toLowerCase())
.parameter(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_VALUE).toString())
.create();
}
private static SimpleCondition createInCategoryCondition(final ActionCondition actionCondition) {
return builder()
.field(actionCondition.getParameterValues().get(InCategoryEvaluator.PARAM_CATEGORY_ASPECT).toString().toLowerCase())
.comparator(COMPARATOR_EQUALS)
.parameter(actionCondition.getParameterValues().get(InCategoryEvaluator.PARAM_CATEGORY_VALUE).toString())
.create();
}
private static SimpleCondition createIsSubtypeCondition(final ActionCondition actionCondition) {
return builder()
.field(IsSubTypeEvaluator.PARAM_TYPE)
.comparator(COMPARATOR_EQUALS)
.parameter(actionCondition.getParameterValues().get(IsSubTypeEvaluator.PARAM_TYPE).toString())
.create();
}
public static Builder builder()
{
return new Builder();
}
public static class Builder
{
private String field;
private String comparator;
private String parameter;
public Builder field(String field)
{
this.field = field;
return this;
}
public Builder comparator(String comparator)
{
this.comparator = comparator;
return this;
}
public Builder parameter(String parameter)
{
this.parameter = parameter;
return this;
}
public SimpleCondition create() {
final SimpleCondition condition = new SimpleCondition();
condition.setField(field);
condition.setComparator(comparator);
condition.setParameter(parameter);
return condition;
}
}
}

View File

@@ -0,0 +1,74 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.nodes;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.rest.api.RuleSets;
import org.alfresco.rest.api.model.rules.RuleSetLink;
import org.alfresco.rest.framework.WebApiDescription;
import org.alfresco.rest.framework.WebApiParam;
import org.alfresco.rest.framework.core.ResourceParameter;
import org.alfresco.rest.framework.resource.RelationshipResource;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.util.PropertyCheck;
import org.springframework.beans.factory.InitializingBean;
@RelationshipResource(name = "rule-set-links", entityResource = NodesEntityResource.class, title = "Linking to a rule set")
public class NodeRuleSetLinksRelation implements InitializingBean, RelationshipResourceAction.Create<RuleSetLink>
{
private final RuleSets ruleSets;
@Override
public void afterPropertiesSet() throws Exception
{
PropertyCheck.mandatory(this, "ruleSets", ruleSets);
}
@WebApiParam(name = "ruleSetLinkRequest", title = "Request body - rule set id",
description = "Request body with rule set id", kind = ResourceParameter.KIND.HTTP_BODY_OBJECT)
@WebApiDescription(title = "Link a rule set to a folder node",
description = "Submits a request to link a rule set to folder",
successStatus = HttpServletResponse.SC_CREATED)
@Override
public List<RuleSetLink> create(String nodeId, List<RuleSetLink> ruleSetLinksBody, Parameters parameters)
{
return ruleSetLinksBody.stream()
.map(r -> ruleSets.linkToRuleSet(nodeId, r.getId()))
.collect(Collectors.toList());
}
public NodeRuleSetLinksRelation(RuleSets ruleSets)
{
this.ruleSets = ruleSets;
}
}

View File

@@ -26,15 +26,84 @@
package org.alfresco.rest.api.nodes;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import org.alfresco.rest.api.RuleSets;
import org.alfresco.rest.api.model.rules.RuleSet;
import org.alfresco.rest.framework.WebApiDescription;
import org.alfresco.rest.framework.core.exceptions.RelationshipResourceNotFoundException;
import org.alfresco.rest.framework.resource.RelationshipResource;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.service.Experimental;
import org.alfresco.util.PropertyCheck;
import org.springframework.beans.factory.InitializingBean;
/**
* Folder node rule sets.
*
*/
@Experimental
@RelationshipResource(name = "rule-sets", entityResource = NodesEntityResource.class, title = "Folder node rule sets")
public class NodeRuleSetsRelation
public class NodeRuleSetsRelation implements RelationshipResourceAction.Read<RuleSet>,
RelationshipResourceAction.ReadById<RuleSet>,
InitializingBean
{
private RuleSets ruleSets;
@Override
public void afterPropertiesSet() throws Exception
{
PropertyCheck.mandatory(this, "ruleSets", ruleSets);
}
/**
* List rule sets for given folder.
* <p>
* - GET /nodes/{folderNodeId}/rule-sets
*
* @param folderNodeId The id of the folder node.
* @param parameters Contains paging information and information about which fields to include
* @return {@link CollectionWithPagingInfo} containing a page of rule sets
*/
@WebApiDescription (
title = "Get rule sets for a folder",
description = "Returns a paged list of rule sets for given node",
successStatus = HttpServletResponse.SC_OK
)
@Override
public CollectionWithPagingInfo<RuleSet> readAll(String folderNodeId, Parameters parameters)
{
return ruleSets.getRuleSets(folderNodeId, parameters.getInclude(), parameters.getPaging());
}
/**
* Get single folder rule for given node's, rule set's and rule's IDs.
* <p>
* - GET /nodes/{folderNodeId}/rule-sets/{ruleSetId}
*
* @param folderNodeId - entity resource context for this relationship
* @param ruleSetId - rule set node ID (associated with folder node)
* @param parameters Contains information about which fields to include
* @return {@link RuleSet} definition
* @throws RelationshipResourceNotFoundException in case resource was not found
*/
@WebApiDescription (
title = "Get rule set",
description = "Returns a single rule set for the given node",
successStatus = HttpServletResponse.SC_OK
)
@Override
public RuleSet readById(String folderNodeId, String ruleSetId, Parameters parameters) throws RelationshipResourceNotFoundException
{
return ruleSets.getRuleSetById(folderNodeId, ruleSetId, parameters.getInclude());
}
public void setRuleSets(RuleSets ruleSets)
{
this.ruleSets = ruleSets;
}
}

View File

@@ -0,0 +1,104 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.nodes;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.rest.api.RuleSettings;
import org.alfresco.rest.api.model.rules.RuleSetting;
import org.alfresco.rest.framework.WebApiDescription;
import org.alfresco.rest.framework.core.exceptions.RelationshipResourceNotFoundException;
import org.alfresco.rest.framework.resource.RelationshipResource;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.service.Experimental;
import org.alfresco.util.PropertyCheck;
import org.springframework.beans.factory.InitializingBean;
/**
* Folder node rule settings (rule inheritance).
*/
@Experimental
@RelationshipResource (name = "rule-settings", entityResource = NodesEntityResource.class, title = "Folder rule settings")
public class NodeRuleSettingsRelation implements RelationshipResourceAction.ReadById<RuleSetting>,
RelationshipResourceAction.Update<RuleSetting>,
InitializingBean
{
private RuleSettings ruleSettings;
@Override
public void afterPropertiesSet() throws Exception
{
PropertyCheck.mandatory(this, "ruleSettings", ruleSettings);
}
/**
* Get the given configuration value for the specified folder.
* <p>
* - GET /nodes/{folderId}/rule-settings/{ruleSettingKey}
*
* @param folderId The id of the folder.
* @param ruleSettingKey The setting to retrieve.
* @param parameters Unused.
* @return {@link RuleSetting} The current value of the setting.
*/
@WebApiDescription (
title = "Get a folder node rule setting",
description = "Returns the specified rule setting for the given folder",
successStatus = HttpServletResponse.SC_OK
)
@Override
public RuleSetting readById(String folderId, String ruleSettingKey, Parameters parameters) throws RelationshipResourceNotFoundException
{
return ruleSettings.getRuleSetting(folderId, ruleSettingKey);
}
/**
* Set the value of a rule setting for the specified folder.
* <p>
* PUT /nodes/{folderId}/rule-settings/{ruleSettingKey}
*
* @param folderId The id of the folder.
* @param ruleSetting The new value of the rule setting.
* @param parameters Unused.
* @return The updated rule setting.
*/
@WebApiDescription (
title = "Update folder node rule setting",
description = "Update a rule setting for given node",
successStatus = HttpServletResponse.SC_OK
)
@Override
public RuleSetting update(String folderId, RuleSetting ruleSetting, Parameters parameters)
{
return ruleSettings.setRuleSetting(folderId, ruleSetting);
}
public void setRuleSettings(RuleSettings ruleSettings)
{
this.ruleSettings = ruleSettings;
}
}

View File

@@ -26,6 +26,9 @@
package org.alfresco.rest.api.nodes;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import org.alfresco.rest.api.Rules;
import org.alfresco.rest.api.model.rules.Rule;
import org.alfresco.rest.framework.WebApiDescription;
@@ -38,15 +41,18 @@ import org.alfresco.service.Experimental;
import org.alfresco.util.PropertyCheck;
import org.springframework.beans.factory.InitializingBean;
import javax.servlet.http.HttpServletResponse;
/**
* Folder node's rules.
*
*/
@Experimental
@RelationshipResource(name = "rules", entityResource = NodeRuleSetsRelation.class, title = "Folder node rules")
public class NodeRulesRelation implements RelationshipResourceAction.Read<Rule>, RelationshipResourceAction.ReadById<Rule>, InitializingBean
public class NodeRulesRelation implements RelationshipResourceAction.Read<Rule>,
RelationshipResourceAction.ReadById<Rule>,
RelationshipResourceAction.Create<Rule>,
RelationshipResourceAction.Update<Rule>,
RelationshipResourceAction.Delete,
InitializingBean
{
private Rules rules;
@@ -76,7 +82,7 @@ public class NodeRulesRelation implements RelationshipResourceAction.Read<Rule>,
{
final String ruleSetId = parameters.getRelationshipId();
return rules.getRules(folderNodeId, ruleSetId, parameters.getPaging());
return rules.getRules(folderNodeId, ruleSetId, parameters.getInclude(), parameters.getPaging());
}
/**
@@ -100,7 +106,76 @@ public class NodeRulesRelation implements RelationshipResourceAction.Read<Rule>,
{
final String ruleId = parameters.getRelationship2Id();
return rules.getRuleById(folderNodeId, ruleSetId, ruleId);
return rules.getRuleById(folderNodeId, ruleSetId, ruleId, parameters.getInclude());
}
/**
* Create one or more rules inside a given folder and rule set.
* <p>
* POST /nodes/{folderNodeId}/rule-sets/{ruleSetId}/rules
*
* @param folderNodeId The folder in which to create the rule.
* @param ruleList The list of rules to create.
* @param parameters List of parameters including the rule set id as the relationship.
* @return The newly created rules.
*/
@WebApiDescription(
title = "Create folder rule",
description = "Creates one or more folder rules for the given folder and rule set",
successStatus = HttpServletResponse.SC_CREATED
)
@Override
public List<Rule> create(String folderNodeId, List<Rule> ruleList, Parameters parameters)
{
final String ruleSetId = parameters.getRelationshipId();
return rules.createRules(folderNodeId, ruleSetId, ruleList, parameters.getInclude());
}
/**
* Update the specified folder rule.
* <p>
* PUT /nodes/{folderNodeId}/rule-sets/{ruleSetId}/rules/{ruleId}
*
* @param folderNodeId The id of the folder containing the rule.
* @param rule The updated rule.
* @param parameters List of parameters including the rule set id and rule id.
* @return The updated rule.
* @throws RelationshipResourceNotFoundException in case resource was not found
*/
@WebApiDescription (
title = "Update folder node rule",
description = "Update a single rule definition for given node's, rule set's and rule's IDs",
successStatus = HttpServletResponse.SC_OK
)
@Override
public Rule update(String folderNodeId, Rule rule, Parameters parameters)
{
String ruleSetId = parameters.getRelationshipId();
String ruleId = parameters.getRelationship2Id();
return rules.updateRuleById(folderNodeId, ruleSetId, ruleId, rule, parameters.getInclude());
}
/**
* Delete single folder rule for given node's, rule set's and rule's IDs.
*
* - DELETE /nodes/{folderNodeId}/rule-sets/{ruleSetId}/rules/{ruleId}
*
* @param folderNodeId - entity resource context for this relationship
* @param ruleSetId - rule set node ID (associated with folder node)
* @param parameters - Should not be null. Should contain at least ruleId (relationship2Id)
* @throws RelationshipResourceNotFoundException in case resource was not found
*/
@WebApiDescription(
title="Delete folder node rule",
description = "Deletes a single rule definition for given node's, rule set's and rule's IDs",
successStatus = HttpServletResponse.SC_NO_CONTENT
)
@Override
public void delete(String folderNodeId, String ruleSetId, Parameters parameters)
{
final String ruleId = parameters.getRelationship2Id();
rules.deleteRuleById(folderNodeId, ruleSetId, ruleId);
}
public void setRules(Rules rules)

View File

@@ -121,8 +121,8 @@ public class ResourceLookupDictionary implements ResourceLocator
return resource;
}
}
logger.warn("Unable to locate resource resource for :"+entityResource+" "+relationResource==null?"":relationResource+" "+property==null?"":property);
throw new NotFoundException("Unable to locate resource resource for :"+entityResource+" "+(relationResource==null?"":relationResource+" "+property==null?"":property));
logger.warn("Unable to locate resource for: "+entityResource+" "+relationResource==null ? "" : relationResource+" "+property==null ? "" : property);
throw new NotFoundException("Unable to locate resource for: "+entityResource+" "+(relationResource==null ? "" : relationResource+" "+property==null ? "" : property));
}
else
{
@@ -160,8 +160,8 @@ public class ResourceLookupDictionary implements ResourceLocator
return resource;
}
}
logger.warn("Unable to locate resource resource for :"+entityResource+" "+relationResource==null?"":relationResource);
throw new NotFoundException("Unable to locate resource resource for :"+entityResource+" "+(relationResource==null?"":relationResource));
logger.warn("Unable to locate resource for: "+entityResource+" "+relationResource==null ? "" : relationResource);
throw new NotFoundException("Unable to locate resource for: "+entityResource+" "+relationResource==null ? "" : relationResource);
}
else
{

View File

@@ -79,6 +79,7 @@ public class ResourceWebScriptPut extends AbstractResourceWebScript implements P
final Map<String, String> resourceVars = locator.parseTemplateVars(req.getServiceMatch().getTemplateVars());
final String entityId = resourceVars.get(ResourceLocator.ENTITY_ID);
final String relationshipId = resourceVars.get(ResourceLocator.RELATIONSHIP_ID);
final String relationship2Id = resourceVars.get(ResourceLocator.RELATIONSHIP2_ID);
final RecognizedParams params = getRecognizedParams(req);
final ResourceOperation operation = resourceMeta.getOperation(HttpMethod.PUT);
@@ -99,9 +100,16 @@ public class ResourceWebScriptPut extends AbstractResourceWebScript implements P
if (StringUtils.isBlank(relationshipId))
{
throw new UnsupportedResourceOperationException("PUT is executed against the instance URL");
} else
}
Object putRel = extractJsonContent(req, assistant.getJsonHelper(), resourceMeta.getObjectType(operation));
if (StringUtils.isNotBlank(relationship2Id))
{
ResourceWebScriptHelper.setUniqueId(putRel, relationship2Id);
return Params.valueOf(false, entityId, relationshipId, relationship2Id,
putRel, null, null, params, null, req);
}
else
{
Object putRel = extractJsonContent(req, assistant.getJsonHelper(), resourceMeta.getObjectType(operation));
ResourceWebScriptHelper.setUniqueId(putRel,relationshipId);
return Params.valueOf(entityId, params, putRel, req);
}

View File

@@ -850,10 +850,65 @@
</property>
</bean>
<bean id="rules" class="org.alfresco.rest.api.impl.RulesImpl">
<bean id="nodeValidator" class="org.alfresco.rest.api.impl.rules.NodeValidator">
<property name="nodes" ref="Nodes" />
<property name="permissionService" ref="PermissionService"/>
<property name="permissionService" ref="PermissionService" />
<property name="ruleService" ref="RuleService" />
<property name="nodeService" ref="NodeService"/>
</bean>
<bean class="org.alfresco.rest.api.nodes.NodeRulesRelation">
<property name="rules" ref="Rules" />
</bean>
<bean id="ruleSetLoader" class="org.alfresco.rest.api.impl.rules.RuleSetLoader">
<property name="nodeService" ref="NodeService" />
</bean>
<bean id="ruleSets" class="org.alfresco.rest.api.impl.rules.RuleSetsImpl">
<property name="ruleSetLoader" ref="ruleSetLoader" />
<property name="validator" ref="nodeValidator" />
<property name="ruleService" ref="RuleService" />
<property name="nodeService" ref="NodeService"/>
<property name="runtimeRuleService" ref="ruleService"/>
</bean>
<bean id="RuleSets" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces" value="org.alfresco.rest.api.RuleSets" />
<property name="target" ref="ruleSets" />
<property name="interceptorNames">
<list>
<idref bean="legacyExceptionInterceptor" />
</list>
</property>
</bean>
<bean id="ruleLoader" class="org.alfresco.rest.api.impl.rules.RuleLoader">
<property name="ruleService" ref="RuleService" />
<property name="nodeValidator" ref="nodeValidator" />
</bean>
<bean class="org.alfresco.rest.api.nodes.NodeRuleSetsRelation">
<property name="ruleSets" ref="RuleSets" />
</bean>
<bean id="actionParameterConverter" class="org.alfresco.rest.api.impl.rules.ActionParameterConverter">
<constructor-arg name="actionService" ref="ActionService"/>
<constructor-arg name="dictionaryService" ref="DictionaryService"/>
<constructor-arg name="namespaceService" ref="NamespaceService"/>
</bean>
<bean id="actionPermissionValidator" class="org.alfresco.rest.api.impl.rules.ActionPermissionValidator">
<constructor-arg name="runtimeActionService" ref="actionService"/>
</bean>
<bean id="rules" class="org.alfresco.rest.api.impl.rules.RulesImpl">
<property name="nodes" ref="Nodes" />
<property name="validator" ref="nodeValidator"/>
<property name="ruleService" ref="RuleService" />
<property name="ruleLoader" ref="ruleLoader"/>
<property name="actionParameterConverter" ref="actionParameterConverter"/>
<property name="actionPermissionValidator" ref="actionPermissionValidator"/>
</bean>
<bean id="Rules" class="org.springframework.aop.framework.ProxyFactoryBean">
@@ -866,8 +921,27 @@
</property>
</bean>
<bean class="org.alfresco.rest.api.nodes.NodeRulesRelation">
<property name="rules" ref="Rules" />
<bean class="org.alfresco.rest.api.nodes.NodeRuleSetLinksRelation">
<constructor-arg name="ruleSets" ref="RuleSets" />
</bean>
<bean id="ruleSettings" class="org.alfresco.rest.api.impl.rules.RuleSettingsImpl">
<property name="validator" ref="nodeValidator" />
<property name="nodeService" ref="NodeService" />
</bean>
<bean id="RuleSettings" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces" value="org.alfresco.rest.api.RuleSettings" />
<property name="target" ref="ruleSettings" />
<property name="interceptorNames">
<list>
<idref bean="legacyExceptionInterceptor" />
</list>
</property>
</bean>
<bean class="org.alfresco.rest.api.nodes.NodeRuleSettingsRelation">
<property name="ruleSettings" ref="RuleSettings" />
</bean>
<bean id="publicapi.mimeTypePropertyLookup" class="org.alfresco.rest.api.lookups.MimeTypePropertyLookup">

View File

@@ -249,6 +249,7 @@
<property name="delegate" ref="webscript.content.streamer" />
<property name="contentService" ref="contentService" />
<property name="repository" ref="repositoryHelper" />
<property name="nonAttachContentTypes" value="#{T(java.util.Arrays).asList('${content.nonAttach.mimetypes}')}" />
</bean>
<!-- Content Info -->

View File

@@ -48,9 +48,8 @@ import org.junit.runners.Suite;
org.alfresco.repo.webdav.RenameShuffleDetectionTest.class,
org.alfresco.repo.webdav.WebDAVHelperTest.class,
org.alfresco.repo.webdav.WebDAVLockServiceImplTest.class,
org.alfresco.rest.api.RulesUnitTests.class,
org.alfresco.rest.api.impl.ContentStorageInformationImplTest.class,
org.alfresco.rest.api.impl.RulesImplTest.class,
org.alfresco.rest.api.nodes.NodeRulesRelationTest.class,
org.alfresco.rest.api.nodes.NodeStorageInfoRelationTest.class,
org.alfresco.rest.api.search.ResultMapperTests.class,
org.alfresco.rest.api.search.SearchApiWebscriptTests.class,

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Share Services AMP
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* Copyright (C) 2005 - 2022 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -66,13 +66,17 @@ public class ContentGetTest extends BaseWebScriptTest
{
super.setUp();
this.authenticationService = (MutableAuthenticationService) getServer().getApplicationContext()
.getBean("AuthenticationService");
this.authenticationService = (MutableAuthenticationService)getServer().getApplicationContext().getBean("AuthenticationService");
this.personService = (PersonService) getServer().getApplicationContext().getBean("PersonService");
this.nodeService = (NodeService) getServer().getApplicationContext().getBean("NodeService");
this.contentService = (ContentService) getServer().getApplicationContext().getBean("ContentService");
AuthenticationUtil.setAdminUserAsFullyAuthenticatedUser();
createUser(USER_ONE);
Repository repositoryHelper = (Repository) getServer().getApplicationContext().getBean("repositoryHelper");
NodeRef companyHome = repositoryHelper.getCompanyHome();
rootFolder = createNode(companyHome, "rootFolder", ContentModel.TYPE_FOLDER);
}
private void createUser(String userName)
@@ -117,18 +121,13 @@ public class ContentGetTest extends BaseWebScriptTest
*/
public void testRelativePath() throws Exception
{
Repository repositoryHelper = (Repository) getServer().getApplicationContext().getBean("repositoryHelper");
NodeRef companyHome = repositoryHelper.getCompanyHome();
rootFolder = createNode(companyHome, "rootFolder", ContentModel.TYPE_FOLDER);
NodeRef doc1 = createNodeWithTextContent(rootFolder, "doc1", ContentModel.TYPE_CONTENT, "doc1 file content");
NodeRef doc1 = createNodeWithTextContent(rootFolder, "doc1", ContentModel.TYPE_CONTENT, "doc1 file content", MimetypeMap.MIMETYPE_TEXT_PLAIN);
NodeRef folderX = createNode(rootFolder, "X", ContentModel.TYPE_FOLDER);
NodeRef folderY = createNode(folderX, "Y", ContentModel.TYPE_FOLDER);
NodeRef folderZ = createNode(folderY, "Z", ContentModel.TYPE_FOLDER);
NodeRef doc2 = createNodeWithTextContent(folderZ, "doc2", ContentModel.TYPE_CONTENT, "doc2 file content");
NodeRef doc2 = createNodeWithTextContent(folderZ, "doc2", ContentModel.TYPE_CONTENT, "doc2 file content", MimetypeMap.MIMETYPE_TEXT_PLAIN);
// uri with relative path at the end
String uri = URL_CONTENT_DOWNLOAD + doc1.getId() + "/X/Y/Z/doc2";
@@ -138,7 +137,46 @@ public class ContentGetTest extends BaseWebScriptTest
Assert.assertEquals("doc2 file content", resp.getContentAsString());
}
public NodeRef createNodeWithTextContent(NodeRef parentNode, String nodeCmName, QName nodeType, String content)
public void testForcedAttachment() throws Exception
{
NodeRef testhtml = createNodeWithTextContent(rootFolder, "testhtml", ContentModel.TYPE_CONTENT, "testhtml content", MimetypeMap.MIMETYPE_HTML);
NodeRef testpdf = createNodeWithTextContent(rootFolder, "testpdf", ContentModel.TYPE_CONTENT, "testpdf content", MimetypeMap.MIMETYPE_PDF);
String uri = URL_CONTENT_DOWNLOAD + testhtml.getId() + "?a=false";
GetRequest req = new GetRequest(uri);
Response res = sendRequest(req, 200);
assertEquals("attachment", res.getHeader("Content-Disposition"));
assertEquals(MimetypeMap.MIMETYPE_HTML + ";charset=UTF-8", res.getContentType());
uri = URL_CONTENT_DOWNLOAD + testhtml.getId();
res = sendRequest(new GetRequest(uri), 200);
assertEquals("attachment", res.getHeader("Content-Disposition"));
assertEquals(MimetypeMap.MIMETYPE_HTML + ";charset=UTF-8", res.getContentType());
uri = URL_CONTENT_DOWNLOAD + testhtml.getId() + "?a=true";
res = sendRequest(new GetRequest(uri), 200);
assertEquals("attachment", res.getHeader("Content-Disposition"));
assertEquals(MimetypeMap.MIMETYPE_HTML + ";charset=UTF-8", res.getContentType());
uri = URL_CONTENT_DOWNLOAD + testpdf.getId() + "?a=false";
res = sendRequest(new GetRequest(uri), 200);
assertNull(res.getHeader("Content-Disposition"));
assertEquals(MimetypeMap.MIMETYPE_PDF + ";charset=UTF-8", res.getContentType());
uri = URL_CONTENT_DOWNLOAD + testpdf.getId();
res = sendRequest(new GetRequest(uri), 200);
assertNull(res.getHeader("Content-Disposition"));
assertEquals(MimetypeMap.MIMETYPE_PDF + ";charset=UTF-8", res.getContentType());
uri = URL_CONTENT_DOWNLOAD + testpdf.getId() + "?a=true";
res = sendRequest(new GetRequest(uri), 200);
assertEquals("attachment", res.getHeader("Content-Disposition"));
assertEquals(MimetypeMap.MIMETYPE_PDF + ";charset=UTF-8", res.getContentType());
}
public NodeRef createNodeWithTextContent(NodeRef parentNode, String nodeCmName, QName nodeType, String content, String mimetype)
{
NodeRef nodeRef = createNode(parentNode, nodeCmName, nodeType);
@@ -146,7 +184,7 @@ public class ContentGetTest extends BaseWebScriptTest
if (content != null)
{
ContentWriter writer = contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
writer.setMimetype(mimetype);
writer.setEncoding("UTF-8");
writer.putContent(content);
}

View File

@@ -1,28 +1,28 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.repo.web.util;
import java.io.BufferedReader;
@@ -32,6 +32,7 @@ import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
import java.util.Date;
import javax.servlet.ServletContext;
@@ -44,7 +45,8 @@ import org.alfresco.util.TempFileProvider;
import org.alfresco.util.WebApplicationContextLoader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.http.UriCompliance;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext;
import org.springframework.beans.BeanUtils;
@@ -145,6 +147,8 @@ public abstract class AbstractJettyComponent implements JettyComponent
configureWebAppContext(webAppContext);
ignoreAmbiguousLinks(server);
server.start();
if(logger.isDebugEnabled())
@@ -203,15 +207,27 @@ public abstract class AbstractJettyComponent implements JettyComponent
}
}
});
// with a login-config in web.xml, jetty seems to require this in order to start successfully
webAppContext.getSecurityHandler().setLoginService(new HashLoginService());
// arbitrary temporary file location
File tmp = new File(TempFileProvider.getSystemTempDir(), String.valueOf(System.currentTimeMillis()));
webAppContext.setResourceBase(tmp.getAbsolutePath());
}
/**
* In newer jetty versions there is a stricter check for links e.g. "//" is not allowed, which clashes
* with some of our tests, because even a NodeRef triggers it - "workspace://..."
* Since Jetty is only used in tests it's alright to block this behaviour.
*
* @param server
*/
private void ignoreAmbiguousLinks(Server server) {
Arrays.stream(server.getConnectors())
.flatMap(c -> c.getConnectionFactories().stream())
.filter(cf -> cf instanceof HttpConnectionFactory)
.map(cf -> (HttpConnectionFactory) cf)
.forEach(hcf -> hcf.getHttpConfiguration().setUriCompliance(UriCompliance.RFC3986));
}
public void shutdown()
{
try

View File

@@ -0,0 +1,55 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api;
import org.alfresco.rest.api.impl.rules.NodeValidatorTest;
import org.alfresco.rest.api.impl.rules.RuleSetsImplTest;
import org.alfresco.rest.api.model.rules.ActionTest;
import org.alfresco.rest.api.model.rules.CompositeConditionTest;
import org.alfresco.rest.api.impl.rules.RulesImplTest;
import org.alfresco.rest.api.model.rules.RuleTest;
import org.alfresco.rest.api.model.rules.SimpleConditionTest;
import org.alfresco.rest.api.nodes.NodeRulesRelationTest;
import org.alfresco.service.Experimental;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@Experimental
@RunWith(Suite.class)
@Suite.SuiteClasses({
NodeRulesRelationTest.class,
RulesImplTest.class,
RuleSetsImplTest.class,
NodeValidatorTest.class,
RuleTest.class,
ActionTest.class,
SimpleConditionTest.class,
CompositeConditionTest.class
})
public class RulesUnitTests
{
}

View File

@@ -1,290 +0,0 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.impl;
import junit.framework.TestCase;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.model.rules.Rule;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.rule.RuleService;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collection;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
@Experimental
@RunWith(MockitoJUnitRunner.class)
public class RulesImplTest extends TestCase
{
private static final String FOLDER_NODE_ID = "dummy-folder-node-id";
private static final String RULE_SET_ID = "dummy-rule-set-id";
private static final String RULE_ID = "dummy-rule-id";
private static final NodeRef folderNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, FOLDER_NODE_ID);
private static final NodeRef ruleSetNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_SET_ID);
private static final NodeRef ruleNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_ID);
private static final Paging paging = Paging.DEFAULT;
@Mock
private Nodes nodesMock;
@Mock
private PermissionService permissionServiceMock;
@Mock
private RuleService ruleServiceMock;
@InjectMocks
private RulesImpl rules;
@Before
@Override
public void setUp() throws Exception
{
MockitoAnnotations.openMocks(this);
given(nodesMock.validateOrLookupNode(eq(FOLDER_NODE_ID), any())).willReturn(folderNodeRef);
given(nodesMock.validateNode(eq(RULE_SET_ID))).willReturn(ruleSetNodeRef);
given(nodesMock.nodeMatches(any(), any(), any())).willReturn(true);
given(permissionServiceMock.hasReadPermission(any())).willReturn(AccessStatus.ALLOWED);
}
@Test
public void testGetRules()
{
given(ruleServiceMock.isRuleSetAssociatedWithFolder(any(), any())).willReturn(true);
given(ruleServiceMock.getRules(any())).willReturn(List.of(createRule(RULE_ID)));
// when
final CollectionWithPagingInfo<Rule> rulesPage = rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging);
then(nodesMock).should().validateOrLookupNode(eq(FOLDER_NODE_ID), isNull());
then(nodesMock).should().validateNode(eq(RULE_SET_ID));
then(nodesMock).should().nodeMatches(eq(folderNodeRef), any(), isNull());
then(nodesMock).should().nodeMatches(eq(ruleSetNodeRef), any(), isNull());
then(nodesMock).shouldHaveNoMoreInteractions();
then(permissionServiceMock).should().hasReadPermission(eq(folderNodeRef));
then(permissionServiceMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(eq(ruleSetNodeRef), eq(folderNodeRef));
then(ruleServiceMock).should().getRules(eq(folderNodeRef));
then(ruleServiceMock).shouldHaveNoMoreInteractions();
assertThat(rulesPage)
.isNotNull()
.extracting(CollectionWithPagingInfo::getCollection)
.isNotNull()
.extracting(Collection::size)
.isEqualTo(1);
assertThat(rulesPage.getCollection().stream().findFirst().orElse(null))
.isNotNull()
.extracting(Rule::getId)
.isEqualTo(RULE_ID);
}
@Test
public void testGetRulesForDefaultRuleSet()
{
final String defaultRuleSetId = "-default-";
given(ruleServiceMock.getRules(any())).willReturn(List.of(createRule(RULE_ID)));
// when
final CollectionWithPagingInfo<Rule> rulesPage = rules.getRules(FOLDER_NODE_ID, defaultRuleSetId, paging);
then(nodesMock).should().validateOrLookupNode(eq(FOLDER_NODE_ID), isNull());
then(nodesMock).should().nodeMatches(eq(folderNodeRef), any(), isNull());
then(nodesMock).shouldHaveNoMoreInteractions();
then(permissionServiceMock).should().hasReadPermission(eq(folderNodeRef));
then(permissionServiceMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().getRuleSetNode(eq(folderNodeRef));
then(ruleServiceMock).should().getRules(eq(folderNodeRef));
then(ruleServiceMock).shouldHaveNoMoreInteractions();
assertThat(rulesPage)
.isNotNull()
.extracting(CollectionWithPagingInfo::getCollection)
.isNotNull()
.extracting(Collection::size)
.isEqualTo(1);
assertThat(rulesPage.getCollection().stream().findFirst().orElse(null))
.isNotNull()
.extracting(Rule::getId)
.isEqualTo(RULE_ID);
}
@Test
public void testGetRulesForNotExistingFolderNode()
{
given(nodesMock.nodeMatches(eq(folderNodeRef), any(), any())).willReturn(false);
// when
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
() -> rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging));
then(ruleServiceMock).shouldHaveNoInteractions();
}
@Test
public void testGetRulesForNotExistingRuleSetNode()
{
given(nodesMock.nodeMatches(eq(folderNodeRef), any(), any())).willReturn(true);
given(nodesMock.nodeMatches(eq(ruleSetNodeRef), any(), any())).willReturn(false);
// when
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
() -> rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging));
then(ruleServiceMock).shouldHaveNoInteractions();
}
@Test
public void testGetRulesForNotAssociatedRuleSetToFolder()
{
given(ruleServiceMock.isRuleSetAssociatedWithFolder(any(), any())).willReturn(false);
// when
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
() -> rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging));
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(eq(ruleSetNodeRef), eq(folderNodeRef));
then(ruleServiceMock).shouldHaveNoMoreInteractions();
}
@Test
public void testGetRulesWithoutReadPermission()
{
given(permissionServiceMock.hasReadPermission(any())).willReturn(AccessStatus.DENIED);
// when
assertThatExceptionOfType(PermissionDeniedException.class).isThrownBy(
() -> rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging));
then(ruleServiceMock).shouldHaveNoInteractions();
}
@Test
public void testGetRuleById()
{
given(nodesMock.validateNode(eq(RULE_ID))).willReturn(ruleNodeRef);
given(ruleServiceMock.isRuleSetAssociatedWithFolder(any(), any())).willReturn(true);
given(ruleServiceMock.isRuleAssociatedWithRuleSet(any(), any())).willReturn(true);
given(ruleServiceMock.getRule(any())).willReturn(createRule(RULE_ID));
// when
final Rule rule = rules.getRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID);
then(nodesMock).should().validateOrLookupNode(eq(FOLDER_NODE_ID), isNull());
then(nodesMock).should().validateNode(eq(RULE_SET_ID));
then(nodesMock).should().validateNode(eq(RULE_ID));
then(nodesMock).should().nodeMatches(eq(folderNodeRef), any(), isNull());
then(nodesMock).should().nodeMatches(eq(ruleSetNodeRef), any(), isNull());
then(nodesMock).should().nodeMatches(eq(ruleNodeRef), any(), isNull());
then(nodesMock).shouldHaveNoMoreInteractions();
then(permissionServiceMock).should().hasReadPermission(eq(folderNodeRef));
then(permissionServiceMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(eq(ruleSetNodeRef), eq(folderNodeRef));
then(ruleServiceMock).should().isRuleAssociatedWithRuleSet(eq(ruleNodeRef), eq(ruleSetNodeRef));
then(ruleServiceMock).should().getRule(eq(ruleNodeRef));
then(ruleServiceMock).shouldHaveNoMoreInteractions();
assertThat(rule)
.isNotNull()
.extracting(Rule::getId)
.isEqualTo(RULE_ID);
}
@Test
public void testGetRuleByIdForDefaultRuleSet()
{
final String defaultRuleSetId = "-default-";
given(nodesMock.validateNode(eq(RULE_ID))).willReturn(ruleNodeRef);
given(ruleServiceMock.getRuleSetNode(any())).willReturn(ruleSetNodeRef);
given(ruleServiceMock.isRuleAssociatedWithRuleSet(any(), any())).willReturn(true);
given(ruleServiceMock.getRule(any())).willReturn(createRule(RULE_ID));
// when
final Rule rule = rules.getRuleById(FOLDER_NODE_ID, defaultRuleSetId, RULE_ID);
then(nodesMock).should().validateOrLookupNode(eq(FOLDER_NODE_ID), isNull());
then(nodesMock).should().validateNode(eq(RULE_ID));
then(nodesMock).should().nodeMatches(eq(folderNodeRef), any(), isNull());
then(nodesMock).should().nodeMatches(eq(ruleNodeRef), any(), isNull());
then(nodesMock).shouldHaveNoMoreInteractions();
then(permissionServiceMock).should().hasReadPermission(eq(folderNodeRef));
then(permissionServiceMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().getRuleSetNode(eq(folderNodeRef));
then(ruleServiceMock).should().isRuleAssociatedWithRuleSet(eq(ruleNodeRef), eq(ruleSetNodeRef));
then(ruleServiceMock).should().getRule(eq(ruleNodeRef));
then(ruleServiceMock).shouldHaveNoMoreInteractions();
assertThat(rule)
.isNotNull()
.extracting(Rule::getId)
.isEqualTo(RULE_ID);
}
@Test
public void testGetRuleByIdForNotAssociatedRuleToRuleSet()
{
given(nodesMock.validateNode(eq(RULE_SET_ID))).willReturn(ruleSetNodeRef);
given(nodesMock.validateNode(eq(RULE_ID))).willReturn(ruleNodeRef);
given(ruleServiceMock.isRuleSetAssociatedWithFolder(any(), any())).willReturn(true);
given(ruleServiceMock.isRuleAssociatedWithRuleSet(any(), any())).willReturn(false);
// when
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
() -> rules.getRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID));
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(eq(ruleSetNodeRef), eq(folderNodeRef));
then(ruleServiceMock).should().isRuleAssociatedWithRuleSet(eq(ruleNodeRef), eq(ruleSetNodeRef));
then(ruleServiceMock).shouldHaveNoMoreInteractions();
}
private static org.alfresco.service.cmr.rule.Rule createRule(final String id) {
final org.alfresco.service.cmr.rule.Rule rule = new org.alfresco.service.cmr.rule.Rule();
rule.setNodeRef(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, id));
return rule;
}
}

View File

@@ -0,0 +1,592 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.impl.rules;
import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.times;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.action.executer.AddFeaturesActionExecuter;
import org.alfresco.repo.action.executer.CheckInActionExecuter;
import org.alfresco.repo.action.executer.CheckOutActionExecuter;
import org.alfresco.repo.action.executer.CopyActionExecuter;
import org.alfresco.repo.action.executer.LinkCategoryActionExecuter;
import org.alfresco.repo.action.executer.MoveActionExecuter;
import org.alfresco.repo.action.executer.RemoveFeaturesActionExecuter;
import org.alfresco.repo.action.executer.ScriptActionExecuter;
import org.alfresco.repo.action.executer.SetPropertyValueActionExecuter;
import org.alfresco.repo.action.executer.SimpleWorkflowActionExecuter;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.action.ActionDefinition;
import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
@Experimental
@RunWith(MockitoJUnitRunner.class)
public class ActionParameterConverterTest
{
private static final String VERSIONABLE = "versionable";
private static final String VERSIONABLE_ASPECT = NamespaceService.CONTENT_MODEL_PREFIX + QName.NAMESPACE_PREFIX + VERSIONABLE;
private static final String CHECKOUT = "checkout";
private static final String CHECKOUT_ASPECT = NamespaceService.CONTENT_MODEL_PREFIX + QName.NAMESPACE_PREFIX + CHECKOUT;
private static final String CONTAINS = "contains";
private static final String CONTAINS_ASPECT = NamespaceService.CONTENT_MODEL_PREFIX + QName.NAMESPACE_PREFIX + CONTAINS;
private static final String CLASSIFIABLE = "generalclassifiable";
private static final String CLASSIFIABLE_ASPECT = NamespaceService.CONTENT_MODEL_PREFIX + QName.NAMESPACE_PREFIX + CLASSIFIABLE;
private static final String IDENTIFIER = "identifier";
private static final String IDENTIFIER_ASPECT = NamespaceService.CONTENT_MODEL_PREFIX + QName.NAMESPACE_PREFIX + IDENTIFIER;
private static final String DUMMY_FOLDER_NODE_ID = "dummy-folder-node";
private static final String DUMMY_SCRIPT_NODE_ID = "dummy-script-ref";
@Mock
private DictionaryService dictionaryService;
@Mock
private ActionService actionService;
@Mock
private NamespaceService namespaceService;
@Mock
private ActionDefinition actionDefinition;
@Mock
private ParameterDefinition actionDefinitionParam1;
@Mock
private ParameterDefinition actionDefinitionParam2;
@Mock
private ParameterDefinition actionDefinitionParam3;
@Mock
private DataTypeDefinition dataTypeDefinition1;
@Mock
private DataTypeDefinition dataTypeDefinition2;
@Mock
private DataTypeDefinition dataTypeDefinition3;
@InjectMocks
private ActionParameterConverter objectUnderTest;
@Test
public void testAddAspectConversion()
{
final String name = AddFeaturesActionExecuter.NAME;
final String aspectNameKey = AddFeaturesActionExecuter.PARAM_ASPECT_NAME;
final Map<String, Serializable> params = Map.of(aspectNameKey, VERSIONABLE_ASPECT);
given(actionService.getActionDefinition(name)).willReturn(actionDefinition);
given(actionDefinition.getParameterDefintion(aspectNameKey)).willReturn(actionDefinitionParam1);
final QName qname = DataTypeDefinition.QNAME;
given(actionDefinitionParam1.getType()).willReturn(qname);
given(dictionaryService.getDataType(qname)).willReturn(dataTypeDefinition1);
given(namespaceService.getNamespaceURI(any())).willReturn(NamespaceService.DICTIONARY_MODEL_1_0_URI);
//when
final Map<String, Serializable> convertedParams = objectUnderTest.getConvertedParams(params, name);
then(actionService).should().getActionDefinition(name);
then(actionService).shouldHaveNoMoreInteractions();
then(actionDefinition).should().getParameterDefintion(aspectNameKey);
then(actionDefinition).shouldHaveNoMoreInteractions();
then(dictionaryService).should().getDataType(qname);
then(dictionaryService).shouldHaveNoMoreInteractions();
then(namespaceService).should().getNamespaceURI(any());
then(namespaceService).shouldHaveNoMoreInteractions();
final Serializable convertedParam = convertedParams.get(aspectNameKey);
assertTrue(convertedParam instanceof QName);
assertEquals(VERSIONABLE, ((QName) convertedParam).getLocalName());
assertEquals(VERSIONABLE_ASPECT, ((QName) convertedParam).getPrefixString());
assertEquals(NamespaceService.DICTIONARY_MODEL_1_0_URI, ((QName) convertedParam).getNamespaceURI());
}
@Test
public void testCopyConversion()
{
final String name = CopyActionExecuter.NAME;
final String destinationFolderKey = CopyActionExecuter.PARAM_DESTINATION_FOLDER;
final String deepCopyKey = CopyActionExecuter.PARAM_DEEP_COPY;
final Map<String, Serializable> params = Map.of(destinationFolderKey, DUMMY_FOLDER_NODE_ID, deepCopyKey, true);
given(actionService.getActionDefinition(name)).willReturn(actionDefinition);
given(actionDefinition.getParameterDefintion(destinationFolderKey)).willReturn(actionDefinitionParam1);
given(actionDefinition.getParameterDefintion(deepCopyKey)).willReturn(actionDefinitionParam2);
final QName nodeRef = DataTypeDefinition.NODE_REF;
given(actionDefinitionParam1.getType()).willReturn(nodeRef);
final QName bool = DataTypeDefinition.BOOLEAN;
given(actionDefinitionParam2.getType()).willReturn(bool);
given(dictionaryService.getDataType(nodeRef)).willReturn(dataTypeDefinition1);
given(dictionaryService.getDataType(bool)).willReturn(dataTypeDefinition2);
given(dataTypeDefinition2.getJavaClassName()).willReturn(Boolean.class.getName());
//when
final Map<String, Serializable> convertedParams = objectUnderTest.getConvertedParams(params, name);
then(actionService).should().getActionDefinition(name);
then(actionService).shouldHaveNoMoreInteractions();
then(actionDefinition).should().getParameterDefintion(destinationFolderKey);
then(actionDefinition).should().getParameterDefintion(deepCopyKey);
then(actionDefinition).shouldHaveNoMoreInteractions();
then(dictionaryService).should(times(2)).getDataType(bool);
then(dictionaryService).should().getDataType(nodeRef);
then(dictionaryService).shouldHaveNoMoreInteractions();
then(namespaceService).shouldHaveNoInteractions();
final Serializable convertedCopyParam = convertedParams.get(destinationFolderKey);
assertTrue(convertedCopyParam instanceof NodeRef);
assertEquals(STORE_REF_WORKSPACE_SPACESSTORE, ((NodeRef) convertedCopyParam).getStoreRef());
assertEquals(DUMMY_FOLDER_NODE_ID, ((NodeRef) convertedCopyParam).getId());
final Serializable convertedDeepCopyParam = convertedParams.get(deepCopyKey);
assertThat(convertedDeepCopyParam instanceof Boolean).isTrue();
assertTrue(((Boolean) convertedDeepCopyParam));
}
@Test
public void testExecuteScriptConversion()
{
final String name = ScriptActionExecuter.NAME;
final String executeScriptKey = ScriptActionExecuter.PARAM_SCRIPTREF;
final Map<String, Serializable> params = Map.of(executeScriptKey, DUMMY_SCRIPT_NODE_ID);
given(actionService.getActionDefinition(name)).willReturn(actionDefinition);
given(actionDefinition.getParameterDefintion(executeScriptKey)).willReturn(actionDefinitionParam1);
final QName scriptNodeRef = DataTypeDefinition.NODE_REF;
given(actionDefinitionParam1.getType()).willReturn(scriptNodeRef);
given(dictionaryService.getDataType(scriptNodeRef)).willReturn(dataTypeDefinition1);
//when
final Map<String, Serializable> convertedParams = objectUnderTest.getConvertedParams(params, name);
then(actionService).should().getActionDefinition(name);
then(actionService).shouldHaveNoMoreInteractions();
then(actionDefinition).should().getParameterDefintion(executeScriptKey);
then(actionDefinition).shouldHaveNoMoreInteractions();
then(dictionaryService).should().getDataType(scriptNodeRef);
then(dictionaryService).shouldHaveNoMoreInteractions();
then(namespaceService).shouldHaveNoInteractions();
final Serializable convertedCopyParam = convertedParams.get(executeScriptKey);
assertTrue(convertedCopyParam instanceof NodeRef);
assertEquals(STORE_REF_WORKSPACE_SPACESSTORE, ((NodeRef) convertedCopyParam).getStoreRef());
assertEquals(DUMMY_SCRIPT_NODE_ID, ((NodeRef) convertedCopyParam).getId());
}
@Test
public void testMoveConversion()
{
final String name = MoveActionExecuter.NAME;
final String destinationFolderKey = MoveActionExecuter.PARAM_DESTINATION_FOLDER;
final Map<String, Serializable> params = Map.of(destinationFolderKey, DUMMY_FOLDER_NODE_ID);
given(actionService.getActionDefinition(name)).willReturn(actionDefinition);
given(actionDefinition.getParameterDefintion(destinationFolderKey)).willReturn(actionDefinitionParam1);
final QName nodeRef = DataTypeDefinition.NODE_REF;
given(actionDefinitionParam1.getType()).willReturn(nodeRef);
given(dictionaryService.getDataType(nodeRef)).willReturn(dataTypeDefinition1);
//when
final Map<String, Serializable> convertedParams = objectUnderTest.getConvertedParams(params, name);
then(actionService).should().getActionDefinition(name);
then(actionService).shouldHaveNoMoreInteractions();
then(actionDefinition).should().getParameterDefintion(destinationFolderKey);
then(actionDefinition).shouldHaveNoMoreInteractions();
then(dictionaryService).should().getDataType(nodeRef);
then(dictionaryService).shouldHaveNoMoreInteractions();
then(namespaceService).shouldHaveNoInteractions();
final Serializable convertedCopyParam = convertedParams.get(destinationFolderKey);
assertTrue(convertedCopyParam instanceof NodeRef);
assertEquals(STORE_REF_WORKSPACE_SPACESSTORE, ((NodeRef) convertedCopyParam).getStoreRef());
assertEquals(DUMMY_FOLDER_NODE_ID, ((NodeRef) convertedCopyParam).getId());
}
@Test
public void testCheckInConversion()
{
final String name = CheckInActionExecuter.NAME;
final String descriptionKey = CheckInActionExecuter.PARAM_DESCRIPTION;
final String minorChangeKey = CheckInActionExecuter.PARAM_MINOR_CHANGE;
String description = "dummy description";
final Map<String, Serializable> params = Map.of(descriptionKey, description, minorChangeKey, true);
given(actionService.getActionDefinition(name)).willReturn(actionDefinition);
given(actionDefinition.getParameterDefintion(descriptionKey)).willReturn(actionDefinitionParam1);
given(actionDefinition.getParameterDefintion(minorChangeKey)).willReturn(actionDefinitionParam2);
final QName text = DataTypeDefinition.TEXT;
given(actionDefinitionParam1.getType()).willReturn(text);
final QName bool = DataTypeDefinition.BOOLEAN;
given(actionDefinitionParam2.getType()).willReturn(bool);
given(dictionaryService.getDataType(text)).willReturn(dataTypeDefinition1);
given(dataTypeDefinition1.getJavaClassName()).willReturn(String.class.getName());
given(dictionaryService.getDataType(bool)).willReturn(dataTypeDefinition2);
given(dataTypeDefinition2.getJavaClassName()).willReturn(Boolean.class.getName());
//when
final Map<String, Serializable> convertedParams = objectUnderTest.getConvertedParams(params, name);
then(actionService).should().getActionDefinition(name);
then(actionService).shouldHaveNoMoreInteractions();
then(actionDefinition).should().getParameterDefintion(descriptionKey);
then(actionDefinition).should().getParameterDefintion(minorChangeKey);
then(actionDefinition).shouldHaveNoMoreInteractions();
then(dictionaryService).should(times(2)).getDataType(bool);
then(dictionaryService).should(times(2)).getDataType(text);
then(dictionaryService).shouldHaveNoMoreInteractions();
then(namespaceService).shouldHaveNoInteractions();
final Serializable convertedDescriptionParam = convertedParams.get(descriptionKey);
assertTrue(convertedDescriptionParam instanceof String);
assertEquals(description, convertedDescriptionParam);
final Serializable convertedMinorChangeParam = convertedParams.get(minorChangeKey);
assertTrue(convertedMinorChangeParam instanceof Boolean);
assertTrue((Boolean) convertedMinorChangeParam);
}
@Test
public void testCheckOutConversion()
{
final String name = CheckOutActionExecuter.NAME;
final String destinationFolderKey = CheckOutActionExecuter.PARAM_DESTINATION_FOLDER;
final String assocNameKey = CheckOutActionExecuter.PARAM_ASSOC_QNAME;
final String assocTypeKey = CheckOutActionExecuter.PARAM_ASSOC_TYPE_QNAME;
final Map<String, Serializable> params =
Map.of(destinationFolderKey, DUMMY_FOLDER_NODE_ID, assocNameKey, CHECKOUT_ASPECT, assocTypeKey, CONTAINS_ASPECT);
given(actionService.getActionDefinition(name)).willReturn(actionDefinition);
given(actionDefinition.getParameterDefintion(destinationFolderKey)).willReturn(actionDefinitionParam1);
final QName nodeRef = DataTypeDefinition.NODE_REF;
given(actionDefinitionParam1.getType()).willReturn(nodeRef);
given(actionDefinition.getParameterDefintion(assocNameKey)).willReturn(actionDefinitionParam2);
final QName qname = DataTypeDefinition.QNAME;
given(actionDefinitionParam2.getType()).willReturn(qname);
given(actionDefinition.getParameterDefintion(assocTypeKey)).willReturn(actionDefinitionParam3);
given(actionDefinitionParam3.getType()).willReturn(qname);
given(dictionaryService.getDataType(nodeRef)).willReturn(dataTypeDefinition1);
given(dictionaryService.getDataType(qname)).willReturn(dataTypeDefinition2);
given(namespaceService.getNamespaceURI(any())).willReturn(NamespaceService.DICTIONARY_MODEL_1_0_URI);
//when
final Map<String, Serializable> convertedParams = objectUnderTest.getConvertedParams(params, name);
then(actionService).should().getActionDefinition(name);
then(actionService).shouldHaveNoMoreInteractions();
then(actionDefinition).should().getParameterDefintion(destinationFolderKey);
then(actionDefinition).should().getParameterDefintion(assocNameKey);
then(actionDefinition).should().getParameterDefintion(assocTypeKey);
then(actionDefinition).shouldHaveNoMoreInteractions();
then(dictionaryService).should(times(2)).getDataType(qname);
then(dictionaryService).should().getDataType(nodeRef);
then(dictionaryService).shouldHaveNoMoreInteractions();
then(namespaceService).should(times(2)).getNamespaceURI(any());
then(namespaceService).shouldHaveNoMoreInteractions();
final Serializable convertedDestinationParam = convertedParams.get(destinationFolderKey);
assertTrue(convertedDestinationParam instanceof NodeRef);
assertEquals(STORE_REF_WORKSPACE_SPACESSTORE, ((NodeRef) convertedDestinationParam).getStoreRef());
assertEquals(DUMMY_FOLDER_NODE_ID, ((NodeRef) convertedDestinationParam).getId());
final Serializable convertedAssocNameParam = convertedParams.get(assocNameKey);
assertTrue(convertedAssocNameParam instanceof QName);
assertEquals(CHECKOUT, ((QName) convertedAssocNameParam).getLocalName());
assertEquals(CHECKOUT_ASPECT, ((QName) convertedAssocNameParam).getPrefixString());
assertEquals(NamespaceService.DICTIONARY_MODEL_1_0_URI, ((QName) convertedAssocNameParam).getNamespaceURI());
final Serializable convertedAssocTypeParam = convertedParams.get(assocTypeKey);
assertTrue(convertedAssocTypeParam instanceof QName);
assertEquals(CONTAINS, ((QName) convertedAssocTypeParam).getLocalName());
assertEquals(CONTAINS_ASPECT, ((QName) convertedAssocTypeParam).getPrefixString());
assertEquals(NamespaceService.DICTIONARY_MODEL_1_0_URI, ((QName) convertedAssocTypeParam).getNamespaceURI());
}
@Test
public void testCategoryLinkConversion()
{
final String name = LinkCategoryActionExecuter.NAME;
final String categoryAspectKey = LinkCategoryActionExecuter.PARAM_CATEGORY_ASPECT;
final String categoryValueKey = LinkCategoryActionExecuter.PARAM_CATEGORY_VALUE;
final Map<String, Serializable> params = Map.of(categoryAspectKey, CLASSIFIABLE_ASPECT, categoryValueKey, DUMMY_FOLDER_NODE_ID);
given(actionService.getActionDefinition(name)).willReturn(actionDefinition);
given(actionDefinition.getParameterDefintion(categoryAspectKey)).willReturn(actionDefinitionParam1);
final QName qname = DataTypeDefinition.QNAME;
given(actionDefinitionParam1.getType()).willReturn(qname);
given(actionDefinition.getParameterDefintion(categoryValueKey)).willReturn(actionDefinitionParam2);
final QName nodeRef = DataTypeDefinition.NODE_REF;
given(actionDefinitionParam2.getType()).willReturn(nodeRef);
given(dictionaryService.getDataType(nodeRef)).willReturn(dataTypeDefinition1);
given(dictionaryService.getDataType(qname)).willReturn(dataTypeDefinition2);
given(namespaceService.getNamespaceURI(any())).willReturn(NamespaceService.DICTIONARY_MODEL_1_0_URI);
//when
final Map<String, Serializable> convertedParams = objectUnderTest.getConvertedParams(params, name);
then(actionService).should().getActionDefinition(name);
then(actionService).shouldHaveNoMoreInteractions();
then(actionDefinition).should().getParameterDefintion(categoryAspectKey);
then(actionDefinition).should().getParameterDefintion(categoryValueKey);
then(actionDefinition).shouldHaveNoMoreInteractions();
then(dictionaryService).should().getDataType(qname);
then(dictionaryService).should().getDataType(nodeRef);
then(dictionaryService).shouldHaveNoMoreInteractions();
then(namespaceService).should().getNamespaceURI(any());
then(namespaceService).shouldHaveNoMoreInteractions();
final Serializable convertedCatValueParam = convertedParams.get(categoryAspectKey);
assertTrue(convertedCatValueParam instanceof QName);
assertEquals(CLASSIFIABLE, ((QName) convertedCatValueParam).getLocalName());
assertEquals(CLASSIFIABLE_ASPECT, ((QName) convertedCatValueParam).getPrefixString());
assertEquals(NamespaceService.DICTIONARY_MODEL_1_0_URI, ((QName) convertedCatValueParam).getNamespaceURI());
final Serializable convertedDestinationParam = convertedParams.get(categoryValueKey);
assertTrue(convertedDestinationParam instanceof NodeRef);
assertEquals(STORE_REF_WORKSPACE_SPACESSTORE, ((NodeRef) convertedDestinationParam).getStoreRef());
assertEquals(DUMMY_FOLDER_NODE_ID, ((NodeRef) convertedDestinationParam).getId());
}
@Test
public void testRemoveAspectConversion()
{
final String name = RemoveFeaturesActionExecuter.NAME;
final String aspectNameKey = RemoveFeaturesActionExecuter.PARAM_ASPECT_NAME;
final Map<String, Serializable> params = Map.of(aspectNameKey, VERSIONABLE_ASPECT);
given(actionService.getActionDefinition(name)).willReturn(actionDefinition);
given(actionDefinition.getParameterDefintion(aspectNameKey)).willReturn(actionDefinitionParam1);
final QName qname = DataTypeDefinition.QNAME;
given(actionDefinitionParam1.getType()).willReturn(qname);
given(dictionaryService.getDataType(qname)).willReturn(dataTypeDefinition1);
given(namespaceService.getNamespaceURI(any())).willReturn(NamespaceService.DICTIONARY_MODEL_1_0_URI);
//when
final Map<String, Serializable> convertedParams = objectUnderTest.getConvertedParams(params, name);
then(actionService).should().getActionDefinition(name);
then(actionService).shouldHaveNoMoreInteractions();
then(actionDefinition).should().getParameterDefintion(aspectNameKey);
then(actionDefinition).shouldHaveNoMoreInteractions();
then(dictionaryService).should().getDataType(qname);
then(dictionaryService).shouldHaveNoMoreInteractions();
then(namespaceService).should().getNamespaceURI(any());
then(namespaceService).shouldHaveNoMoreInteractions();
final Serializable convertedParam = convertedParams.get(aspectNameKey);
assertTrue(convertedParam instanceof QName);
assertEquals(VERSIONABLE, ((QName) convertedParam).getLocalName());
assertEquals(VERSIONABLE_ASPECT, ((QName) convertedParam).getPrefixString());
assertEquals(NamespaceService.DICTIONARY_MODEL_1_0_URI, ((QName) convertedParam).getNamespaceURI());
}
@Test
public void testAddWorkflowConversion()
{
final String name = SimpleWorkflowActionExecuter.NAME;
final String approveStepKey = SimpleWorkflowActionExecuter.PARAM_APPROVE_STEP;
final String approveFolderKey = SimpleWorkflowActionExecuter.PARAM_APPROVE_FOLDER;
final String approveMoveKey = SimpleWorkflowActionExecuter.PARAM_APPROVE_MOVE;
final String rejectStepKey = SimpleWorkflowActionExecuter.PARAM_REJECT_STEP;
final String rejectFolderKey = SimpleWorkflowActionExecuter.PARAM_REJECT_FOLDER;
final String rejectMoveKey = SimpleWorkflowActionExecuter.PARAM_REJECT_MOVE;
final String approve = "Approve";
final String reject = "Reject";
final Map<String, Serializable> params =
Map.of(approveStepKey, approve, approveFolderKey, DUMMY_FOLDER_NODE_ID, approveMoveKey, true,
rejectStepKey, reject, rejectFolderKey, DUMMY_FOLDER_NODE_ID, rejectMoveKey, true);
given(actionService.getActionDefinition(name)).willReturn(actionDefinition);
given(actionDefinition.getParameterDefintion(rejectStepKey)).willReturn(actionDefinitionParam1);
given(actionDefinition.getParameterDefintion(approveStepKey)).willReturn(actionDefinitionParam1);
final QName text = DataTypeDefinition.TEXT;
given(actionDefinitionParam1.getType()).willReturn(text, text);
given(actionDefinition.getParameterDefintion(rejectFolderKey)).willReturn(actionDefinitionParam2);
given(actionDefinition.getParameterDefintion(approveFolderKey)).willReturn(actionDefinitionParam2);
final QName nodeRef = DataTypeDefinition.NODE_REF;
given(actionDefinitionParam2.getType()).willReturn(nodeRef, nodeRef);
given(actionDefinition.getParameterDefintion(rejectMoveKey)).willReturn(actionDefinitionParam3);
given(actionDefinition.getParameterDefintion(approveMoveKey)).willReturn(actionDefinitionParam3);
final QName bool = DataTypeDefinition.BOOLEAN;
given(actionDefinitionParam3.getType()).willReturn(bool, bool);
given(dictionaryService.getDataType(nodeRef)).willReturn(dataTypeDefinition1);
given(dictionaryService.getDataType(text)).willReturn(dataTypeDefinition2);
given(dataTypeDefinition2.getJavaClassName()).willReturn(String.class.getName());
given(dictionaryService.getDataType(bool)).willReturn(dataTypeDefinition3);
given(dataTypeDefinition3.getJavaClassName()).willReturn(Boolean.class.getName());
//when
final Map<String, Serializable> convertedParams = objectUnderTest.getConvertedParams(params, name);
then(actionService).should().getActionDefinition(name);
then(actionService).shouldHaveNoMoreInteractions();
then(actionDefinition).should().getParameterDefintion(approveStepKey);
then(actionDefinition).should().getParameterDefintion(approveFolderKey);
then(actionDefinition).should().getParameterDefintion(approveMoveKey);
then(actionDefinition).should().getParameterDefintion(rejectStepKey);
then(actionDefinition).should().getParameterDefintion(rejectFolderKey);
then(actionDefinition).should().getParameterDefintion(rejectMoveKey);
then(actionDefinition).shouldHaveNoMoreInteractions();
then(dictionaryService).should(times(4)).getDataType(text);
then(dictionaryService).should(times(2)).getDataType(nodeRef);
then(dictionaryService).should(times(4)).getDataType(bool);
then(dictionaryService).shouldHaveNoMoreInteractions();
then(namespaceService).shouldHaveNoInteractions();
final Serializable convertedApproveStepParam = convertedParams.get(approveStepKey);
assertTrue(convertedApproveStepParam instanceof String);
assertEquals(approve, convertedApproveStepParam);
final Serializable convertedRejectStepParam = convertedParams.get(rejectStepKey);
assertTrue(convertedRejectStepParam instanceof String);
assertEquals(reject, convertedRejectStepParam);
final Serializable convertedApproveFolderParam = convertedParams.get(approveFolderKey);
assertTrue(convertedApproveFolderParam instanceof NodeRef);
assertEquals(STORE_REF_WORKSPACE_SPACESSTORE, ((NodeRef) convertedApproveFolderParam).getStoreRef());
assertEquals(DUMMY_FOLDER_NODE_ID, ((NodeRef) convertedApproveFolderParam).getId());
final Serializable convertedRejectFolderParam = convertedParams.get(rejectFolderKey);
assertTrue(convertedRejectFolderParam instanceof NodeRef);
assertEquals(STORE_REF_WORKSPACE_SPACESSTORE, ((NodeRef) convertedRejectFolderParam).getStoreRef());
assertEquals(DUMMY_FOLDER_NODE_ID, ((NodeRef) convertedRejectFolderParam).getId());
final Serializable convertedApproveMoveParam = convertedParams.get(approveMoveKey);
assertTrue(convertedApproveMoveParam instanceof Boolean);
assertTrue((Boolean) convertedApproveMoveParam);
final Serializable convertedRejectMoveParam = convertedParams.get(rejectMoveKey);
assertTrue(convertedRejectMoveParam instanceof Boolean);
assertTrue((Boolean) convertedRejectMoveParam);
}
@Test
public void testSetPropertyConversion()
{
final String name = SetPropertyValueActionExecuter.NAME;
final String propertyNameKey = SetPropertyValueActionExecuter.PARAM_PROPERTY;
final String propertyValueKey = SetPropertyValueActionExecuter.PARAM_VALUE;
final String propertyTypeKey = "prop_type";
final String dummy_key_value = "dummy_key_value";
final String propType = "d:text";
final Map<String, Serializable> params =
Map.of(propertyNameKey, IDENTIFIER_ASPECT, propertyValueKey, dummy_key_value, propertyTypeKey, propType);
given(actionService.getActionDefinition(name)).willReturn(actionDefinition);
given(actionDefinition.getParameterDefintion(propertyNameKey)).willReturn(actionDefinitionParam1);
final QName qname = DataTypeDefinition.QNAME;
given(actionDefinitionParam1.getType()).willReturn(qname);
given(actionDefinition.getParameterDefintion(propertyValueKey)).willReturn(actionDefinitionParam2);
final QName any = DataTypeDefinition.ANY;
given(actionDefinitionParam2.getType()).willReturn(any);
given(actionDefinition.getParameterDefintion(propertyTypeKey)).willReturn(null);
given(actionDefinition.getAdhocPropertiesAllowed()).willReturn(true);
given(dictionaryService.getDataType(qname)).willReturn(dataTypeDefinition1);
given(dictionaryService.getDataType(any)).willReturn(dataTypeDefinition2);
given(dataTypeDefinition2.getJavaClassName()).willReturn(Object.class.getName());
given(namespaceService.getNamespaceURI(any())).willReturn(NamespaceService.DICTIONARY_MODEL_1_0_URI);
//when
final Map<String, Serializable> convertedParams = objectUnderTest.getConvertedParams(params, name);
then(actionService).should().getActionDefinition(name);
then(actionService).shouldHaveNoMoreInteractions();
then(actionDefinition).should().getParameterDefintion(propertyNameKey);
then(actionDefinition).should().getParameterDefintion(propertyValueKey);
then(actionDefinition).should().getParameterDefintion(propertyTypeKey);
then(actionDefinition).should().getAdhocPropertiesAllowed();
then(actionDefinition).shouldHaveNoMoreInteractions();
then(dictionaryService).should().getDataType(qname);
then(dictionaryService).should(times(2)).getDataType(any);
then(dictionaryService).shouldHaveNoMoreInteractions();
then(namespaceService).should().getNamespaceURI(any());
then(namespaceService).shouldHaveNoMoreInteractions();
final Serializable convertedPropNameParam = convertedParams.get(propertyNameKey);
assertTrue(convertedPropNameParam instanceof QName);
assertEquals(IDENTIFIER, ((QName) convertedPropNameParam).getLocalName());
assertEquals(IDENTIFIER_ASPECT, ((QName) convertedPropNameParam).getPrefixString());
assertEquals(NamespaceService.DICTIONARY_MODEL_1_0_URI, ((QName) convertedPropNameParam).getNamespaceURI());
final Serializable convertedPropValParam = convertedParams.get(propertyValueKey);
assertTrue(convertedPropValParam instanceof String);
assertEquals(dummy_key_value, convertedPropValParam);
final Serializable convertedPropTypeParam = convertedParams.get(propertyTypeKey);
assertTrue(convertedPropTypeParam instanceof String);
assertEquals(propType, convertedPropTypeParam);
}
@Test
public void testQnameServiceModelParamConversion() {
given(namespaceService.getPrefixes(any())).willReturn(List.of("cm"));
final String qname = "{cm-dummy-prefix}audio";
final Serializable qnameParam = QName.createQName(qname);
//when
final Serializable convertedParam = objectUnderTest.convertParamFromServiceModel(qnameParam);
then(namespaceService).should().getPrefixes(any());
then(namespaceService).shouldHaveNoMoreInteractions();
assertEquals("cm:audio", convertedParam);
}
@Test
public void testNodeRefServiceModelParamConversion() {
//given
final Serializable nodeRefParam = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, DUMMY_FOLDER_NODE_ID);
//when
final Serializable convertedParam = objectUnderTest.convertParamFromServiceModel(nodeRefParam);
then(namespaceService).shouldHaveNoInteractions();
assertEquals(DUMMY_FOLDER_NODE_ID, convertedParam);
}
@Test
public void testOtherServiceModelParamConversion() {
//given
final Serializable dummyStringParam = "dummy-param";
//when
final Serializable convertedParam = objectUnderTest.convertParamFromServiceModel(dummyStringParam);
then(namespaceService).shouldHaveNoInteractions();
assertEquals(dummyStringParam, convertedParam);
}
}

View File

@@ -0,0 +1,117 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.impl.rules;
import static org.alfresco.service.cmr.rule.RuleType.INBOUND;
import static org.alfresco.service.cmr.rule.RuleType.OUTBOUND;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.BDDMockito.then;
import java.util.List;
import junit.framework.TestCase;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.repo.action.CompositeActionImpl;
import org.alfresco.repo.action.RuntimeActionService;
import org.alfresco.repo.action.executer.CheckOutActionExecuter;
import org.alfresco.repo.action.executer.CopyActionExecuter;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.rule.Rule;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
@Experimental
@RunWith(MockitoJUnitRunner.class)
public class ActionPermissionValidatorTest extends TestCase
{
private static final String DUMMY_NODE_ID = "dummy-node-id";
@Mock
private RuntimeActionService runtimeActionService;
@InjectMocks
private ActionPermissionValidator objectUnderTest;
@Test
public void testPositiveRulePermissionValidation()
{
//given
final CompositeActionImpl compositeAction =
new CompositeActionImpl(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, DUMMY_NODE_ID), "composite-id");
final Action action1 = new ActionImpl(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, DUMMY_NODE_ID), "id-1",
CopyActionExecuter.NAME);
compositeAction.addAction(action1);
final Action action2 = new ActionImpl(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, DUMMY_NODE_ID), "id-2",
CheckOutActionExecuter.NAME);
compositeAction.addAction(action2);
final Rule inputRule = new Rule();
inputRule.setAction(compositeAction);
inputRule.setRuleTypes(List.of(INBOUND));
//when
final Rule validatedRule = objectUnderTest.validateRulePermissions(inputRule);
then(runtimeActionService).should().verifyActionAccessRestrictions(action1);
then(runtimeActionService).should().verifyActionAccessRestrictions(action2);
then(runtimeActionService).shouldHaveNoMoreInteractions();
((CompositeActionImpl) validatedRule.getAction()).getActions()
.forEach(action -> Assertions.assertThat(action.getParameterValue("actionContext")).isEqualTo("rule"));
}
@Test
public void testNegativeRulePermissionValidation()
{
//given
final CompositeActionImpl compositeAction =
new CompositeActionImpl(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, DUMMY_NODE_ID), "composite-id");
final Action action1 = new ActionImpl(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, DUMMY_NODE_ID), "id-1",
CopyActionExecuter.NAME);
compositeAction.addAction(action1);
final Action action2 = new ActionImpl(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, DUMMY_NODE_ID), "id-2",
CheckOutActionExecuter.NAME);
compositeAction.addAction(action2);
final Rule inputRule = new Rule();
inputRule.setAction(compositeAction);
inputRule.setRuleTypes(List.of(OUTBOUND));
//when
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(() -> objectUnderTest.validateRulePermissions(inputRule));
then(runtimeActionService).should().verifyActionAccessRestrictions(action1);
then(runtimeActionService).should().verifyActionAccessRestrictions(action2);
then(runtimeActionService).shouldHaveNoMoreInteractions();
}
}

View File

@@ -0,0 +1,441 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.impl.rules;
import static org.alfresco.model.ContentModel.TYPE_FOLDER;
import static org.alfresco.model.ContentModel.TYPE_SYSTEM_FOLDER;
import static org.alfresco.repo.rule.RuleModel.TYPE_RULE;
import static org.alfresco.rest.api.model.rules.RuleSet.DEFAULT_ID;
import static org.alfresco.service.cmr.security.AccessStatus.ALLOWED;
import static org.alfresco.service.cmr.security.AccessStatus.DENIED;
import static org.alfresco.service.cmr.security.PermissionService.CHANGE_PERMISSIONS;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.reset;
import java.util.Set;
import org.alfresco.model.ContentModel;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.model.Node;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
import org.alfresco.rest.framework.core.exceptions.RelationshipResourceNotFoundException;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.rule.RuleService;
import org.alfresco.service.cmr.security.PermissionService;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
public class NodeValidatorTest
{
private static final String FOLDER_NODE_ID = "dummy-folder-node-id";
private static final String LINK_TO_NODE_ID = "dummy-link-to-node-id";
private static final String RULE_SET_ID = "dummy-rule-set-id";
private static final String RULE_ID = "dummy-rule-id";
private static final String PARENT_NODE_ID = "dummy-parent-node-id";
private static final NodeRef folderNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, FOLDER_NODE_ID);
private static final NodeRef ruleSetNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_SET_ID);
private static final NodeRef ruleNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_ID);
private static final NodeRef parentNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARENT_NODE_ID);
@Mock
private Nodes nodesMock;
@Mock
private Node ruleSetNodeMock;
@Mock
private PermissionService permissionServiceMock;
@Mock
private RuleService ruleServiceMock;
@Mock
private NodeService nodeServiceMock;
@Mock
private ChildAssociationRef primaryParentMock;
@InjectMocks
private NodeValidator nodeValidator;
@Before
public void setUp() throws Exception
{
MockitoAnnotations.openMocks(this);
given(nodesMock.validateOrLookupNode(eq(FOLDER_NODE_ID), any())).willReturn(folderNodeRef);
given(nodesMock.validateNode(RULE_SET_ID)).willReturn(ruleSetNodeRef);
given(nodesMock.validateNode(RULE_ID)).willReturn(ruleNodeRef);
given(nodesMock.nodeMatches(any(), any(), any())).willReturn(true);
given(permissionServiceMock.hasReadPermission(any())).willReturn(ALLOWED);
given(permissionServiceMock.hasPermission(any(), any())).willReturn(ALLOWED);
}
@Test
public void testValidateFolderNode()
{
// when
final NodeRef nodeRef = nodeValidator.validateFolderNode(FOLDER_NODE_ID, false);
then(nodesMock).should().validateOrLookupNode(FOLDER_NODE_ID, null);
then(nodesMock).should().nodeMatches(folderNodeRef, Set.of(TYPE_FOLDER), null);
then(nodesMock).shouldHaveNoMoreInteractions();
then(permissionServiceMock).should().hasReadPermission(folderNodeRef);
then(permissionServiceMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
assertThat(nodeRef).isNotNull().isEqualTo(folderNodeRef);
}
@Test
public void testValidateFolderNode_notExistingFolder()
{
given(nodesMock.validateOrLookupNode(any(), any())).willThrow(new EntityNotFoundException(FOLDER_NODE_ID));
//when
assertThatExceptionOfType(EntityNotFoundException.class).isThrownBy(
() -> nodeValidator.validateFolderNode(FOLDER_NODE_ID, false));
then(nodesMock).should().validateOrLookupNode(FOLDER_NODE_ID, null);
then(nodesMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
}
@Test
public void testValidateFolderNode_notMatchingTypeFolder()
{
given(nodesMock.nodeMatches(any(), eq(Set.of(TYPE_FOLDER)), any())).willReturn(false);
// when
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
() -> nodeValidator.validateFolderNode(FOLDER_NODE_ID, false));
then(nodesMock).should().validateOrLookupNode(FOLDER_NODE_ID, null);
then(nodesMock).should().nodeMatches(folderNodeRef, Set.of(TYPE_FOLDER), null);
then(nodesMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
}
@Test
public void testValidateFolderNode_noReadPermission()
{
given(permissionServiceMock.hasReadPermission(any())).willReturn(DENIED);
// when
assertThatExceptionOfType(PermissionDeniedException.class).isThrownBy(
() -> nodeValidator.validateFolderNode(FOLDER_NODE_ID, false));
then(permissionServiceMock).should().hasReadPermission(folderNodeRef);
then(permissionServiceMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
}
@Test
public void testValidateFolderNode_noChangePermission()
{
given(permissionServiceMock.hasPermission(any(), any())).willReturn(DENIED);
// when
assertThatExceptionOfType(PermissionDeniedException.class).isThrownBy(() ->
nodeValidator.validateFolderNode(folderNodeRef.getId(), true));
then(permissionServiceMock).should().hasPermission(folderNodeRef, CHANGE_PERMISSIONS);
then(permissionServiceMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoMoreInteractions();
}
@Test
public void validateRuleSetNode()
{
given(ruleServiceMock.isRuleSetAssociatedWithFolder(any(), any())).willReturn(true);
// when
final NodeRef nodeRef = nodeValidator.validateRuleSetNode(RULE_SET_ID, folderNodeRef);
then(nodesMock).should().validateNode(RULE_SET_ID);
then(nodesMock).should().nodeMatches(ruleSetNodeRef, Set.of(TYPE_SYSTEM_FOLDER), null);
then(nodesMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
then(permissionServiceMock).shouldHaveNoInteractions();
assertThat(nodeRef).isNotNull().isEqualTo(ruleSetNodeRef);
}
@Test
public void testValidateRuleSetNodeNoParentId()
{
given(nodesMock.getNode(any())).willReturn(ruleSetNodeMock);
given(nodeServiceMock.getPrimaryParent(any())).willReturn(primaryParentMock);
given(primaryParentMock.getParentRef()).willReturn(parentNodeRef);
//when
final NodeRef nodeRef = nodeValidator.validateRuleSetNode(LINK_TO_NODE_ID,true);
assertThat(nodeRef).isNotNull().isEqualTo(parentNodeRef);
}
@Test
public void validateRuleSetNode_defaultId()
{
given(ruleServiceMock.getRuleSetNode(any())).willReturn(ruleSetNodeRef);
// when
final NodeRef nodeRef = nodeValidator.validateRuleSetNode(DEFAULT_ID, folderNodeRef);
then(ruleServiceMock).should().getRuleSetNode(folderNodeRef);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
then(nodesMock).shouldHaveNoInteractions();
then(permissionServiceMock).shouldHaveNoInteractions();
assertThat(nodeRef).isNotNull().isEqualTo(ruleSetNodeRef);
}
@Test
public void testValidateRuleSetNode_notExistingRuleSet()
{
given(nodesMock.validateNode(RULE_SET_ID)).willThrow(new EntityNotFoundException(RULE_SET_ID));
//when
assertThatExceptionOfType(EntityNotFoundException.class).isThrownBy(
() -> nodeValidator.validateRuleSetNode(RULE_SET_ID, folderNodeRef));
then(nodesMock).should().validateNode(RULE_SET_ID);
then(nodesMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
}
@Test
public void testValidateRuleSetNode_notMatchingTypeSystemFolder()
{
given(nodesMock.nodeMatches(any(), eq(Set.of(TYPE_SYSTEM_FOLDER)), any())).willReturn(false);
// when
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
() -> nodeValidator.validateRuleSetNode(RULE_SET_ID, folderNodeRef));
then(nodesMock).should().validateNode(RULE_SET_ID);
then(nodesMock).should().nodeMatches(ruleSetNodeRef, Set.of(TYPE_SYSTEM_FOLDER), null);
then(nodesMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
}
@Test
public void testValidateRuleSetNode_notExistingDefaultRuleSet()
{
given(ruleServiceMock.getRuleSetNode(folderNodeRef)).willReturn(null);
// when
assertThatExceptionOfType(RelationshipResourceNotFoundException.class).isThrownBy(
() -> nodeValidator.validateRuleSetNode(DEFAULT_ID, folderNodeRef));
then(ruleServiceMock).should().getRuleSetNode(folderNodeRef);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
then(nodesMock).shouldHaveNoInteractions();
}
@Test
public void testValidateRuleSetNode_notAssociatedRuleSetToFolder()
{
given(ruleServiceMock.isRuleSetAssociatedWithFolder(any(), any())).willReturn(false);
// when
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
() -> nodeValidator.validateRuleSetNode(RULE_SET_ID, folderNodeRef));
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
}
@Test
public void validateRuleNode()
{
given(ruleServiceMock.isRuleAssociatedWithRuleSet(any(), any())).willReturn(true);
// when
final NodeRef nodeRef = nodeValidator.validateRuleNode(RULE_ID, ruleSetNodeRef);
then(nodesMock).should().validateNode(RULE_ID);
then(nodesMock).should().nodeMatches(ruleNodeRef, Set.of(TYPE_RULE), null);
then(nodesMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().isRuleAssociatedWithRuleSet(ruleNodeRef, ruleSetNodeRef);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
then(permissionServiceMock).shouldHaveNoInteractions();
assertThat(nodeRef).isNotNull().isEqualTo(ruleNodeRef);
}
@Test
public void validateRuleNode_nullRuleSet()
{
// when
final NodeRef nodeRef = nodeValidator.validateRuleNode(RULE_ID, null);
then(nodesMock).should().validateNode(RULE_ID);
then(nodesMock).should().nodeMatches(ruleNodeRef, Set.of(TYPE_RULE), null);
then(nodesMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
then(permissionServiceMock).shouldHaveNoInteractions();
assertThat(nodeRef).isNotNull().isEqualTo(ruleNodeRef);
}
@Test
public void testValidateRuleNode_notExistingRule()
{
given(nodesMock.validateNode(RULE_ID)).willThrow(new EntityNotFoundException(RULE_ID));
//when
assertThatExceptionOfType(EntityNotFoundException.class).isThrownBy(
() -> nodeValidator.validateRuleNode(RULE_ID, ruleSetNodeRef));
then(nodesMock).should().validateNode(RULE_ID);
then(nodesMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
}
@Test
public void testValidateRuleNode_notMatchingTypeRule()
{
given(nodesMock.nodeMatches(any(), eq(Set.of(TYPE_RULE)), any())).willReturn(false);
// when
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
() -> nodeValidator.validateRuleNode(RULE_ID, ruleSetNodeRef));
then(nodesMock).should().validateNode(RULE_ID);
then(nodesMock).should().nodeMatches(ruleNodeRef, Set.of(TYPE_RULE), null);
then(nodesMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
}
@Test
public void testValidateRuleNode_notAssociatedRuleToRuleSet()
{
given(ruleServiceMock.isRuleAssociatedWithRuleSet(any(), any())).willReturn(false);
// when
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
() -> nodeValidator.validateRuleNode(RULE_ID, ruleSetNodeRef));
then(ruleServiceMock).should().isRuleAssociatedWithRuleSet(ruleNodeRef, ruleSetNodeRef);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
}
@Test
public void testIsRuleSetNode()
{
//resetting mock to bypass setup method
resetNodesMock();
boolean actual = nodeValidator.isRuleSetNode(RULE_SET_ID);
Assert.assertTrue(actual);
}
@Test
public void testIsNotRuleSetNode()
{
//resetting mock to bypass setup method
resetNodesMock();
//using an id that doesn't belong to a ruleset node
boolean actual = nodeValidator.isRuleSetNode(FOLDER_NODE_ID);
Assert.assertFalse(actual);
}
@Test
public void testIsRuleSetNotNullAndShared()
{
given(ruleServiceMock.isRuleSetShared(any())).willReturn(true);
// when
final boolean shared = nodeValidator.isRuleSetNotNullAndShared(ruleSetNodeRef);
then(ruleServiceMock).should().isRuleSetShared(ruleSetNodeRef);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
assertThat(shared).isTrue();
}
@Test
public void testIsRuleSetNotNullAndShared_nullRuleSetNode()
{
// when
final boolean shared = nodeValidator.isRuleSetNotNullAndShared(null);
then(ruleServiceMock).shouldHaveNoInteractions();
assertThat(shared).isFalse();
}
@Test
public void testIsRuleSetNotNullAndShared_withoutRuleSetAndWithFolder()
{
given(ruleServiceMock.getRuleSetNode(any())).willReturn(ruleSetNodeRef);
// when
nodeValidator.isRuleSetNotNullAndShared(null, folderNodeRef);
then(ruleServiceMock).should().getRuleSetNode(folderNodeRef);
then(ruleServiceMock).should().isRuleSetShared(ruleSetNodeRef);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
}
@Test
public void testIsRuleSetNotNullAndShared_withRuleSetAndWithFolder()
{
// when
nodeValidator.isRuleSetNotNullAndShared(ruleSetNodeRef, folderNodeRef);
then(ruleServiceMock).should().isRuleSetShared(ruleSetNodeRef);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
}
private void resetNodesMock() {
reset(nodesMock);
given(nodesMock.validateOrLookupNode(eq(FOLDER_NODE_ID), any())).willReturn(folderNodeRef);
given(nodesMock.validateNode(RULE_SET_ID)).willReturn(ruleSetNodeRef);
given(nodesMock.validateNode(RULE_ID)).willReturn(ruleNodeRef);
given(nodesMock.nodeMatches(ruleSetNodeRef, Set.of(ContentModel.TYPE_SYSTEM_FOLDER), null)).willReturn(true);
}
}

View File

@@ -0,0 +1,121 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.impl.rules;
import static java.util.Collections.emptyList;
import static org.alfresco.rest.api.impl.rules.RuleLoader.IS_SHARED;
import static org.alfresco.rest.api.model.rules.RuleTrigger.OUTBOUND;
import static org.alfresco.rest.api.model.rules.RuleTrigger.UPDATE;
import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.MockitoAnnotations.openMocks;
import java.util.List;
import org.alfresco.rest.api.model.rules.Rule;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.rule.RuleService;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
/** Unit tests for {@link RuleLoader}. */
public class RuleLoaderTest
{
private static final String NODE_ID = "node-id";
private static final NodeRef NODE_REF = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, NODE_ID);
private static final String TITLE = "title";
private static final String DESCRIPTION = "description";
private static final boolean ENABLED = true;
private static final boolean CASCADE = true;
private static final boolean EXECUTE_ASYNCHRONOUSLY = false;
private static final List<String> TRIGGERS = List.of("update", "outbound");
private static final NodeRef RULE_SET_NODE = new NodeRef("rule://set/");
@InjectMocks
private RuleLoader ruleLoader;
@Mock
private RuleService ruleServiceMock;
@Mock
private NodeValidator nodeValidatorMock;
private org.alfresco.service.cmr.rule.Rule serviceRule = createServiceRule();
@Before
public void setUp()
{
openMocks(this);
}
@Test
public void testLoadRule()
{
Rule rule = ruleLoader.loadRule(serviceRule, emptyList());
Rule expected = Rule.builder().id(NODE_ID)
.name(TITLE)
.description(DESCRIPTION)
.enabled(ENABLED)
.cascade(CASCADE)
.asynchronous(EXECUTE_ASYNCHRONOUSLY)
.triggers(List.of(UPDATE, OUTBOUND)).create();
assertThat(rule).isEqualTo(expected);
}
@Test
public void testLoadRule_noExceptionWithNullInclude()
{
ruleLoader.loadRule(serviceRule, null);
}
@Test
public void testLoadRule_includeIsShared()
{
// Simulate the rule set being shared.
given(ruleServiceMock.getRuleSetNode(NODE_REF)).willReturn(RULE_SET_NODE);
given(nodeValidatorMock.isRuleSetNotNullAndShared(RULE_SET_NODE)).willReturn(true);
Rule rule = ruleLoader.loadRule(serviceRule, List.of(IS_SHARED));
assertThat(rule).extracting("isShared").isEqualTo(true);
}
private org.alfresco.service.cmr.rule.Rule createServiceRule()
{
org.alfresco.service.cmr.rule.Rule rule = new org.alfresco.service.cmr.rule.Rule();
rule.setNodeRef(NODE_REF);
rule.setTitle(TITLE);
rule.setDescription(DESCRIPTION);
rule.setRuleDisabled(!ENABLED);
rule.applyToChildren(CASCADE);
rule.setExecuteAsynchronously(EXECUTE_ASYNCHRONOUSLY);
rule.setRuleTypes(TRIGGERS);
return rule;
}
}

View File

@@ -0,0 +1,133 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.impl.rules;
import static org.alfresco.rest.api.impl.rules.RuleSetLoader.INCLUSION_TYPE;
import static org.alfresco.rest.api.impl.rules.RuleSetLoader.OWNING_FOLDER;
import static org.alfresco.rest.api.model.rules.InclusionType.INHERITED;
import static org.alfresco.rest.api.model.rules.InclusionType.LINKED;
import static org.alfresco.rest.api.model.rules.InclusionType.OWNED;
import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE;
import static org.mockito.BDDMockito.given;
import java.util.List;
import junit.framework.TestCase;
import org.alfresco.rest.api.model.rules.RuleSet;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
/** Unit tests for {@link RuleSetLoader}. */
@Experimental
@RunWith (MockitoJUnitRunner.class)
public class RuleSetLoaderTest extends TestCase
{
private static final String FOLDER_ID = "dummy-folder-id";
private static final String RULE_SET_ID = "dummy-rule-set-id";
private static final NodeRef FOLDER_NODE = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, FOLDER_ID);
private static final NodeRef RULE_SET_NODE = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, RULE_SET_ID);
private static final String LINKING_FOLDER_ID = "linking-folder";
private static final NodeRef LINKING_FOLDER = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, LINKING_FOLDER_ID);
private static final NodeRef INHERITING_FOLDER = new NodeRef("inheriting://folder/");
@InjectMocks
private RuleSetLoader ruleSetLoader;
@Mock
private NodeService nodeServiceMock;
@Mock
private ChildAssociationRef ruleSetAssociationMock;
@Mock
private ChildAssociationRef linkAssociationMock;
@Before
@Override
public void setUp()
{
given(ruleSetAssociationMock.getParentRef()).willReturn(FOLDER_NODE);
given(nodeServiceMock.getPrimaryParent(RULE_SET_NODE)).willReturn(ruleSetAssociationMock);
given(linkAssociationMock.getParentRef()).willReturn(LINKING_FOLDER);
given(nodeServiceMock.getParentAssocs(RULE_SET_NODE)).willReturn(List.of(ruleSetAssociationMock, linkAssociationMock));
}
@Test
public void testLoadRuleSet_noIncludes()
{
// Call the method under test.
RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, FOLDER_NODE, null);
RuleSet expected = RuleSet.builder().id(RULE_SET_ID).create();
assertEquals(expected, actual);
}
@Test
public void testLoadRuleSet_includeOwningFolder()
{
// Call the method under test.
RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, FOLDER_NODE, List.of(OWNING_FOLDER));
RuleSet expected = RuleSet.builder().id(RULE_SET_ID).owningFolder(FOLDER_NODE).create();
assertEquals(expected, actual);
}
@Test
public void testLoadRuleSet_includeInclusionType()
{
// Call the method under test.
RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, FOLDER_NODE, List.of(INCLUSION_TYPE));
RuleSet expected = RuleSet.builder().id(RULE_SET_ID).inclusionType(OWNED).create();
assertEquals(expected, actual);
}
@Test
public void testLoadRuleSet_linkedInclusionType()
{
// Call the method under test.
RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, LINKING_FOLDER, List.of(INCLUSION_TYPE));
RuleSet expected = RuleSet.builder().id(RULE_SET_ID).inclusionType(LINKED).create();
assertEquals(expected, actual);
}
@Test
public void testLoadRuleSet_inheritedInclusionType()
{
// Call the method under test.
RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, INHERITING_FOLDER, List.of(INCLUSION_TYPE));
RuleSet expected = RuleSet.builder().id(RULE_SET_ID).inclusionType(INHERITED).create();
assertEquals(expected, actual);
}
}

View File

@@ -0,0 +1,236 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 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.api.impl.rules;
import static java.util.Collections.emptyList;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import java.util.Collection;
import java.util.List;
import junit.framework.TestCase;
import org.alfresco.repo.rule.RuleModel;
import org.alfresco.repo.rule.RuntimeRuleService;
import org.alfresco.rest.api.model.rules.RuleSet;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.rule.RuleService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
/** Unit tests for {@link RuleSetsImpl}. */
@Experimental
@RunWith (MockitoJUnitRunner.class)
public class RuleSetsImplTest extends TestCase
{
private static final String FOLDER_ID = "dummy-folder-id";
private static final String LINK_TO_NODE_ID = "dummy-link-to-node-id";
private static final String RULE_SET_ID = "dummy-rule-set-id";
private static final NodeRef FOLDER_NODE = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, FOLDER_ID);
private static final NodeRef LINK_TO_NODE = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, LINK_TO_NODE_ID);
private static final NodeRef RULE_SET_NODE = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_SET_ID);
private static final Paging PAGING = Paging.DEFAULT;
private static final List<String> INCLUDES = List.of("dummy-includes");
@InjectMocks
private RuleSetsImpl ruleSets;
@Mock
private RuleSetLoader ruleSetLoaderMock;
@Mock
private NodeValidator nodeValidatorMock;
@Mock
private NodeService nodeServiceMock;
@Mock
private RuleService ruleServiceMock;
@Mock
private RuntimeRuleService runtimeRuleServiceMock;
@Mock
private RuleSet ruleSetMock;
@Mock
private ChildAssociationRef assocRef;
@Before
@Override
public void setUp()
{
MockitoAnnotations.openMocks(this);
given(nodeValidatorMock.validateFolderNode(eq(LINK_TO_NODE_ID), anyBoolean())).willReturn(LINK_TO_NODE);
given(nodeValidatorMock.validateRuleSetNode(LINK_TO_NODE_ID,true)).willReturn(LINK_TO_NODE);
given(nodeValidatorMock.validateFolderNode(eq(FOLDER_ID), anyBoolean())).willReturn(FOLDER_NODE);
given(nodeValidatorMock.validateRuleSetNode(RULE_SET_ID, FOLDER_NODE)).willReturn(RULE_SET_NODE);
given(ruleServiceMock.getRuleSetNode(FOLDER_NODE)).willReturn(RULE_SET_NODE);
given(ruleSetLoaderMock.loadRuleSet(RULE_SET_NODE, FOLDER_NODE, INCLUDES)).willReturn(ruleSetMock);
}
@Test
public void testGetRuleSets()
{
// Call the method under test.
CollectionWithPagingInfo<RuleSet> actual = ruleSets.getRuleSets(FOLDER_ID, INCLUDES, PAGING);
then(nodeValidatorMock).should().validateFolderNode(FOLDER_ID, false);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().getRuleSetNode(FOLDER_NODE);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
Collection<RuleSet> expected = List.of(ruleSetMock);
assertEquals(expected, actual.getCollection());
assertEquals(PAGING, actual.getPaging());
}
@Test
public void testGetZeroRuleSets()
{
// Simulate no rule sets for the folder.
given(ruleServiceMock.getRuleSetNode(FOLDER_NODE)).willReturn(null);
// Call the method under test.
CollectionWithPagingInfo<RuleSet> actual = ruleSets.getRuleSets(FOLDER_ID, INCLUDES, PAGING);
then(nodeValidatorMock).should().validateFolderNode(FOLDER_ID, false);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().getRuleSetNode(FOLDER_NODE);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
assertEquals(emptyList(), actual.getCollection());
assertEquals(PAGING, actual.getPaging());
}
@Test
public void testGetRuleSetById()
{
// Call the method under test.
RuleSet actual = ruleSets.getRuleSetById(FOLDER_ID, RULE_SET_ID, INCLUDES);
then(nodeValidatorMock).should().validateFolderNode(FOLDER_ID, false);
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, FOLDER_NODE);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
assertEquals(ruleSetMock, actual);
}
@Test
public void testLinkToFolderRuleSet()
{
NodeRef childNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "dummy-child-id");
given(ruleServiceMock.hasRules(any(NodeRef.class))).willReturn(true, false);
given(runtimeRuleServiceMock.getSavedRuleFolderAssoc(any(NodeRef.class))).willReturn(assocRef);
given(assocRef.getChildRef()).willReturn(childNodeRef);
//when
String actual = ruleSets.linkToRuleSet(FOLDER_ID,LINK_TO_NODE_ID).getId();
then(ruleServiceMock).should().hasRules(LINK_TO_NODE);
then(ruleServiceMock).should().hasRules(FOLDER_NODE);
then(runtimeRuleServiceMock).should().getSavedRuleFolderAssoc(LINK_TO_NODE);
then(runtimeRuleServiceMock).shouldHaveNoMoreInteractions();
then(nodeServiceMock).should().addChild(FOLDER_NODE, childNodeRef, RuleModel.ASSOC_RULE_FOLDER, RuleModel.ASSOC_RULE_FOLDER);
then(nodeServiceMock).shouldHaveNoMoreInteractions();
assertEquals(childNodeRef.getId(),actual);
}
@Test
public void testLinkToRuleSet()
{
NodeRef childNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "dummy-child-id");
given(nodeValidatorMock.isRuleSetNode(any())).willReturn(true);
given(ruleServiceMock.hasRules(any(NodeRef.class))).willReturn(true, false);
given(runtimeRuleServiceMock.getSavedRuleFolderAssoc(any(NodeRef.class))).willReturn(assocRef);
given(assocRef.getChildRef()).willReturn(childNodeRef);
//when
String actual = ruleSets.linkToRuleSet(FOLDER_ID,LINK_TO_NODE_ID).getId();
then(nodeValidatorMock).should().validateFolderNode(FOLDER_ID,true);
then(nodeValidatorMock).should().isRuleSetNode(LINK_TO_NODE_ID);
then(nodeValidatorMock).should().validateRuleSetNode(LINK_TO_NODE_ID,true);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().hasRules(LINK_TO_NODE);
then(ruleServiceMock).should().hasRules(FOLDER_NODE);
then(runtimeRuleServiceMock).should().getSavedRuleFolderAssoc(LINK_TO_NODE);
then(runtimeRuleServiceMock).shouldHaveNoMoreInteractions();
then(nodeServiceMock).should().addChild(FOLDER_NODE, childNodeRef, RuleModel.ASSOC_RULE_FOLDER, RuleModel.ASSOC_RULE_FOLDER);
then(nodeServiceMock).shouldHaveNoMoreInteractions();
assertEquals(childNodeRef.getId(),actual);
}
@Test
public void testLinkToRuleSet_targetFolderHasNoRules()
{
given(ruleServiceMock.hasRules(LINK_TO_NODE)).willReturn(false);
//when
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
() -> ruleSets.linkToRuleSet(FOLDER_ID, LINK_TO_NODE_ID)
);
then(nodeServiceMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().hasRules(LINK_TO_NODE);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
then(runtimeRuleServiceMock).shouldHaveNoInteractions();
}
@Test
public void testLinkToRuleSet_folderShouldntHavePreExistingRules()
{
given(ruleServiceMock.hasRules(any(NodeRef.class))).willReturn(true, true);
//when
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
() -> ruleSets.linkToRuleSet(FOLDER_ID, LINK_TO_NODE_ID));
then(nodeServiceMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().hasRules(LINK_TO_NODE);
then(ruleServiceMock).should().hasRules(FOLDER_NODE);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
then(runtimeRuleServiceMock).shouldHaveNoInteractions();
}
}

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