Compare commits

...

129 Commits

Author SHA1 Message Date
mikolajbrzezinski
53ecbaa74f 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

(cherry picked from commit 885f21ff86)
2022-08-10 11:57:47 +02:00
mstrankowski
bc5aabbf37 Check community version 2022-08-10 10:43:28 +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
Travis CI User
99a503a1e1 [maven-release-plugin][skip ci] prepare release 17.49 2022-07-22 09:37:59 +00:00
rrajoria
e60f8fdecc Updating googledrive version 2022-07-22 14:30:14 +05:30
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
Travis CI User
59f414d1b1 [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-18 18:22:47 +00:00
Travis CI User
4b5b61e669 [maven-release-plugin][skip ci] prepare release 17.48 2022-07-18 18:22:44 +00:00
MohinishSah
50a2707069 updating Google docs Alpha version 2022-07-18 23:19:28 +05:30
Travis CI User
82605c1d42 [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-18 14:07:11 +00:00
Travis CI User
72d118c23c [maven-release-plugin][skip ci] prepare release 17.47 2022-07-18 14:07:08 +00:00
rrajoria
9f7285d13d Updating googledrive version (#1226) 2022-07-18 19:02:54 +05:30
Travis CI User
118a55e358 [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-18 11:13:36 +00:00
Travis CI User
2a9265fb30 [maven-release-plugin][skip ci] prepare release 17.46 2022-07-18 11:13:33 +00:00
Grzegorz Oleksy
57f02054c4 ACS-3170 Implement Tests For Mail Actions (#1213)
Added tests for restApi with all 4 external endpoints kept track of (running-actions from v0 wasn't needed, as that only allows admin to run actions).
Unit tests added, 1 spring test to verify admin privilege check in AccessRestriction class.

Co-authored-by: mstrankowski <marcin.strankowski@hyland.com>
2022-07-18 12:37:22 +02:00
Travis CI User
5cb66ebbd0 [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-17 00:07:50 +00:00
Travis CI User
f872e2dc9c [maven-release-plugin][skip ci] prepare release 17.45 2022-07-17 00:07:48 +00:00
Alfresco CI User
b34fdb8f75 [force] Force release for 2022-07-17. 2022-07-17 00:03:04 +00:00
Travis CI User
0a77cca00d [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-16 09:08:23 +00:00
Travis CI User
a18ab6fdd1 [maven-release-plugin][skip ci] prepare release 17.44 2022-07-16 09:08:20 +00:00
Travis CI User
d78e61acde [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-13 15:44:52 +00:00
Travis CI User
1508b599cc [maven-release-plugin][skip ci] prepare release 17.43 2022-07-13 15:44:49 +00:00
krdabrowski
0b7909be40 ACS-3229: Rules v1 REST API - Get rule definition (#1205)
ACS-3229: Rules v1 REST API - Get rule definition
2022-07-13 15:59:29 +02:00
Travis CI User
75b9388a12 [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-12 15:45:43 +00:00
Travis CI User
8936db78a5 [maven-release-plugin][skip ci] prepare release 17.42 2022-07-12 15:45:40 +00:00
dependabot[bot]
c475114030 Bump maven-assembly-plugin from 3.3.0 to 3.4.1 (#1202)
Bumps [maven-assembly-plugin](https://github.com/apache/maven-assembly-plugin) from 3.3.0 to 3.4.1.
- [Release notes](https://github.com/apache/maven-assembly-plugin/releases)
- [Commits](https://github.com/apache/maven-assembly-plugin/compare/maven-assembly-plugin-3.3.0...maven-assembly-plugin-3.4.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-assembly-plugin
  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-07-12 16:12:59 +01:00
Travis CI User
11c4537a53 [maven-release-plugin][skip ci] prepare for next development iteration 2022-07-12 14:19:54 +00:00
107 changed files with 8148 additions and 2248 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

View File

@@ -1,7 +1,7 @@
---
dist: focal
language: java
jdk: openjdk11
jdk: openjdk17
services:
- docker
@@ -51,387 +51,346 @@ jobs:
install: skip
script: travis_retry travis_wait 80 bash scripts/travis/prepare.sh
- name: "Source Clear Scan (SCA)"
stage: test
if: branch = master OR branch =~ /release\/.*/
# Run Veracode
install: skip
script: travis_wait 30 bash scripts/travis/source_clear.sh
- name: "Core, Data-Model, Repository - AllUnitTestsSuite - Build and test"
if: commit_message !~ /\[skip repo\]/
install: skip
script:
- travis_retry mvn -B test -pl core,data-model -am -DfailIfNoTests=false
- travis_retry mvn -B test -pl "repository,mmt" -am "-Dtest=AllUnitTestsSuite,AllMmtUnitTestSuite" -DfailIfNoTests=false
- name: "Repository - AppContext01TestSuite"
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 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
- name: "Repository - AppContext02TestSuite"
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
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 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
- name: "Repository - AppContext04TestSuite"
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 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
- name: "Repository - AppContext05TestSuite"
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
- mkdir -p "${HOME}/tmp"
- cp repository/src/test/resources/realms/alfresco-realm.json "${HOME}/tmp"
- export HOST_IP=$(hostname -I | cut -f1 -d' ')
- docker run -d -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin -e DB_VENDOR=h2 -p 8999:8080 -e KEYCLOAK_IMPORT=/tmp/alfresco-realm.json -v $HOME/tmp/alfresco-realm.json:/tmp/alfresco-realm.json alfresco/alfresco-identity-service:1.2
script: travis_wait 20 mvn -B test -pl repository -am -Dtest=AppContext05TestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco "-Didentity-service.auth-server-url=http://${HOST_IP}:8999/auth"
- name: "Repository - AppContext06TestSuite"
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 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
- name: "Repository - AppContextExtraTestSuite"
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 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
- name: "Repository - MiscContextTestSuite"
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 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
- name: "Repository - SearchTestSuite"
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
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"
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 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
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"
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 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
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"
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 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
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"
# We run tests on the latest version of MariaDB on pull requests plus the normal master and release branches - ignored on feature branches
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip db\]/ ) OR commit_message =~ /\[db\]/ OR commit_message =~ /\[latest db\]/
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
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"
# We run tests on the latest version of MySQL on pull requests plus the normal master and release branches - ignored on feature branches
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip db\]/ ) OR commit_message =~ /\[db\]/ OR commit_message =~ /\[latest db\]/
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
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"
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
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"
# 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\]/
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
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
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
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 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
- name: "Remote-api - AppContext03TestSuite"
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 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
- name: "Remote-api - AppContext04TestSuite"
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 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
- name: "Remote-api - AppContextExtraTestSuite"
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
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"
# TAS tests are generally skipped on feature branches as they will be repeated on the enterprise repo or community packaging builds
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip tas\]/) OR commit_message =~ /\[tas\]/
install: travis_retry travis_wait 40 env REQUIRES_LOCAL_IMAGES=true bash scripts/travis/build.sh
before_script:
- ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal+transforms.yml
- ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
script: travis_wait 60 mvn -B verify -f packaging/tests/tas-restapi/pom.xml -Pall-tas-tests,run-restapi-part1 -Denvironment=default -DrunBugs=false
- name: "REST API TAS tests part2"
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip tas\]/) OR commit_message =~ /\[tas\]/
install: travis_retry travis_wait 40 env REQUIRES_LOCAL_IMAGES=true bash scripts/travis/build.sh
before_script:
- ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal+transforms.yml
- ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
script: travis_wait 60 mvn -B verify -f packaging/tests/tas-restapi/pom.xml -Pall-tas-tests,run-restapi-part2 -Denvironment=default -DrunBugs=false
- name: "REST API TAS tests part3"
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip tas\]/) OR commit_message =~ /\[tas\]/
install: travis_retry travis_wait 40 env REQUIRES_LOCAL_IMAGES=true bash scripts/travis/build.sh
before_script:
- ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal+transforms.yml
- ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
script: travis_wait 60 mvn -B verify -f packaging/tests/tas-restapi/pom.xml -Pall-tas-tests,run-restapi-part3 -Denvironment=default -DrunBugs=false
- name: "CMIS TAS tests - BROWSER binding"
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip tas\]/) OR commit_message =~ /\[tas\]/
install: travis_retry travis_wait 40 env REQUIRES_LOCAL_IMAGES=true bash scripts/travis/build.sh
before_script:
- ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal+transforms.yml
- ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
script: travis_wait 40 mvn -B verify -f packaging/tests/tas-cmis/pom.xml -Pall-tas-tests,run-cmis-browser -Denvironment=default -DrunBugs=false
- name: "CMIS TAS tests - ATOM binding"
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip tas\]/) OR commit_message =~ /\[tas\]/
install: travis_retry travis_wait 40 env REQUIRES_LOCAL_IMAGES=true bash scripts/travis/build.sh
before_script:
- ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal+transforms.yml
- ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
script: travis_wait 40 mvn -B verify -f packaging/tests/tas-cmis/pom.xml -Pall-tas-tests,run-cmis-atom -Denvironment=default -DrunBugs=false
- name: "CMIS TAS tests - WEBSERVICES binding"
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip tas\]/) OR commit_message =~ /\[tas\]/
install: travis_retry travis_wait 40 env REQUIRES_LOCAL_IMAGES=true bash scripts/travis/build.sh
before_script:
- ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal+transforms.yml
- ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
script: travis_wait 40 mvn -B verify -f packaging/tests/tas-cmis/pom.xml -Pall-tas-tests,run-cmis-webservices -Denvironment=default -DrunBugs=false
- name: "Email TAS tests"
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip tas\]/) OR commit_message =~ /\[tas\]/
install: travis_retry travis_wait 40 env REQUIRES_LOCAL_IMAGES=true bash scripts/travis/build.sh
before_script:
- ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal.yml
- ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
script: travis_wait 30 mvn -B verify -f packaging/tests/tas-email/pom.xml -Pall-tas-tests -Denvironment=default -DrunBugs=false
- name: "WebDAV TAS tests"
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip tas\]/) OR commit_message =~ /\[tas\]/
install: travis_retry travis_wait 40 env REQUIRES_LOCAL_IMAGES=true bash scripts/travis/build.sh
before_script:
- ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal.yml
- ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
script: travis_wait 30 mvn -B verify -f packaging/tests/tas-webdav/pom.xml -Pall-tas-tests -Denvironment=default -DrunBugs=false
- name: "Integration TAS tests"
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip tas\]/) OR commit_message =~ /\[tas\]/
install: travis_retry travis_wait 40 env REQUIRES_LOCAL_IMAGES=true bash scripts/travis/build.sh
before_script:
- ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal.yml
- ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
script: travis_wait 30 mvn -B verify -f packaging/tests/tas-integration/pom.xml -Pall-tas-tests -Denvironment=default -DrunBugs=false
- name: "Share Services - ShareServicesTestSuite"
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'
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)"
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip ags\]/) OR commit_message =~ /\[ags\]/
install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
script: travis_retry travis_wait 80 mvn -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-postgres -PagsAllTestSuitePt1 -f amps/ags/pom.xml ${LOG_WARN}
- name: "AGS Integration Tests 02 (PostgreSQL)"
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip ags\]/) OR commit_message =~ /\[ags\]/
install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
script: travis_retry travis_wait 80 mvn -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-postgres -PagsAllTestSuitePt2 -f amps/ags/pom.xml ${LOG_WARN}
- name: "AGS Integration Tests 03 (PostgreSQL)"
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip ags\]/) OR commit_message =~ /\[ags\]/
install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
script: travis_retry travis_wait 80 mvn -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-postgres -PagsAllTestSuitePt3 -f amps/ags/pom.xml ${LOG_WARN}
- name: "AGS Unit & Integration Tests 04 (PostgreSQL)"
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip ags\]/) OR commit_message =~ /\[ags\]/
install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
script: travis_retry travis_wait 80 mvn -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-postgres -PagsAllTestSuitePt4 -f amps/ags/pom.xml ${LOG_WARN}
- name: "AGS Unit & Integration Tests 01 (MySQL) "
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip ags\]/) OR commit_message =~ /\[ags on MySQL\]/
install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
script: travis_retry travis_wait 80 mvn -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-mysql -PagsAllTestSuitePt1 -f amps/ags/pom.xml ${LOG_WARN}
- name: "AGS Integration Tests 02 (MySQL) "
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip ags\]/) OR commit_message =~ /\[ags on MySQL\]/
install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
script: travis_retry travis_wait 80 mvn -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-mysql -PagsAllTestSuitePt2 -f amps/ags/pom.xml ${LOG_WARN}
- name: "AGS Integration Tests 03 (MySQL) "
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip ags\]/) OR commit_message =~ /\[ags\]/
install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
script: travis_retry travis_wait 80 mvn -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-mysql -PagsAllTestSuitePt3 -f amps/ags/pom.xml ${LOG_WARN}
- name: "AGS Unit & Integration Tests 04 (MySQL) "
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip ags\]/) OR commit_message =~ /\[ags on MySQL\]/
install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
script: travis_retry travis_wait 80 mvn -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-mysql -PagsAllTestSuitePt4 -f amps/ags/pom.xml ${LOG_WARN}
- name: "AGS Community Rest API Tests"
if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip ags\]/) OR commit_message =~ /\[ags\]/
install: travis_retry travis_wait 40 env REQUIRES_LOCAL_IMAGES=true bash scripts/travis/build.sh
addons:
artifacts:
paths:
- ./amps/ags/rm-automation/rm-automation-community-rest-api/target/reports/rm-automation-community-rest-api.log
- alfresco.log
- solr.log
target_paths: community/${TRAVIS_BUILD_NUMBER}/${TRAVIS_JOB_NAME}
before_script:
- ${TAS_SCRIPTS}/start-compose.sh ./amps/ags/rm-community/rm-community-repo/docker-compose.yml
- ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8080/alfresco"
script: travis_wait 40 mvn -B test -pl :alfresco-governance-services-automation-community-rest-api -am -DfailIfNoTests=false -Dskip.automationtests=false -Pags
after_script: bash amps/ags/travis/scripts/getLogs.sh
# - name: "Source Clear Scan (SCA)"
# stage: test
# if: branch = master OR branch =~ /release\/.*/
# # Run Veracode
# install: skip
# script: travis_wait 30 bash scripts/travis/source_clear.sh
#
# - name: "Core, Data-Model, Repository - AllUnitTestsSuite - Build and test"
# if: commit_message !~ /\[skip repo\]/
# install: skip
# script:
# - travis_retry mvn -B test -pl core,data-model -am -DfailIfNoTests=false
# - travis_retry mvn -B test -pl "repository,mmt" -am "-Dtest=AllUnitTestsSuite,AllMmtUnitTestSuite" -DfailIfNoTests=false
#
# - name: "Repository - AppContext01TestSuite"
# 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: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
#
# - name: "Repository - AppContext02TestSuite"
# 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: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: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
#
# - name: "Repository - AppContext04TestSuite"
# 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: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
#
# - name: "Repository - AppContext05TestSuite"
# 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: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' ')
# - docker run -d -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin -e DB_VENDOR=h2 -p 8999:8080 -e KEYCLOAK_IMPORT=/tmp/alfresco-realm.json -v $HOME/tmp/alfresco-realm.json:/tmp/alfresco-realm.json alfresco/alfresco-identity-service:1.2
# script: travis_wait 20 mvn -B test -pl repository -am -Dtest=AppContext05TestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco "-Didentity-service.auth-server-url=http://${HOST_IP}:8999/auth"
#
# - name: "Repository - AppContext06TestSuite"
# 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: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
#
# - name: "Repository - AppContextExtraTestSuite"
# 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: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
#
# - name: "Repository - MiscContextTestSuite"
# 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: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
#
# - name: "Repository - SearchTestSuite"
# 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: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"
# 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 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.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"
# 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 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.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"
# 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 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.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"
# # We run tests on the latest version of MariaDB on pull requests plus the normal master and release branches - ignored on feature branches
# if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip db\]/ ) OR commit_message =~ /\[db\]/ OR commit_message =~ /\[latest db\]/
# 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.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"
# # We run tests on the latest version of MySQL on pull requests plus the normal master and release branches - ignored on feature branches
# if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip db\]/ ) OR commit_message =~ /\[db\]/ OR commit_message =~ /\[latest db\]/
# 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.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 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: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 14.4 tests"
# # We only run DB tests on the latest version of PostgreSQL on feature branches
# 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: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.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: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: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
#
# - name: "Remote-api - AppContext03TestSuite"
# 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: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
#
# - name: "Remote-api - AppContext04TestSuite"
# 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: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
#
# - name: "Remote-api - AppContextExtraTestSuite"
# 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: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"
# # TAS tests are generally skipped on feature branches as they will be repeated on the enterprise repo or community packaging builds
# if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip tas\]/) OR commit_message =~ /\[tas\]/
# install: travis_retry travis_wait 40 env REQUIRES_LOCAL_IMAGES=true bash scripts/travis/build.sh
# before_script:
# - ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal+transforms.yml
# - ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
# script: travis_wait 60 mvn -B verify -f packaging/tests/tas-restapi/pom.xml -Pall-tas-tests,run-restapi-part1 -Denvironment=default -DrunBugs=false
#
# - name: "REST API TAS tests part2"
# if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip tas\]/) OR commit_message =~ /\[tas\]/
# install: travis_retry travis_wait 40 env REQUIRES_LOCAL_IMAGES=true bash scripts/travis/build.sh
# before_script:
# - ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal+transforms.yml
# - ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
# script: travis_wait 60 mvn -B verify -f packaging/tests/tas-restapi/pom.xml -Pall-tas-tests,run-restapi-part2 -Denvironment=default -DrunBugs=false
#
# - name: "REST API TAS tests part3"
# if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip tas\]/) OR commit_message =~ /\[tas\]/
# install: travis_retry travis_wait 40 env REQUIRES_LOCAL_IMAGES=true bash scripts/travis/build.sh
# before_script:
# - ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal+transforms.yml
# - ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
# script: travis_wait 60 mvn -B verify -f packaging/tests/tas-restapi/pom.xml -Pall-tas-tests,run-restapi-part3 -Denvironment=default -DrunBugs=false
#
# - name: "CMIS TAS tests - BROWSER binding"
# if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip tas\]/) OR commit_message =~ /\[tas\]/
# install: travis_retry travis_wait 40 env REQUIRES_LOCAL_IMAGES=true bash scripts/travis/build.sh
# before_script:
# - ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal+transforms.yml
# - ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
# script: travis_wait 40 mvn -B verify -f packaging/tests/tas-cmis/pom.xml -Pall-tas-tests,run-cmis-browser -Denvironment=default -DrunBugs=false
#
# - name: "CMIS TAS tests - ATOM binding"
# if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip tas\]/) OR commit_message =~ /\[tas\]/
# install: travis_retry travis_wait 40 env REQUIRES_LOCAL_IMAGES=true bash scripts/travis/build.sh
# before_script:
# - ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal+transforms.yml
# - ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
# script: travis_wait 40 mvn -B verify -f packaging/tests/tas-cmis/pom.xml -Pall-tas-tests,run-cmis-atom -Denvironment=default -DrunBugs=false
#
# - name: "CMIS TAS tests - WEBSERVICES binding"
# if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip tas\]/) OR commit_message =~ /\[tas\]/
# install: travis_retry travis_wait 40 env REQUIRES_LOCAL_IMAGES=true bash scripts/travis/build.sh
# before_script:
# - ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal+transforms.yml
# - ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
# script: travis_wait 40 mvn -B verify -f packaging/tests/tas-cmis/pom.xml -Pall-tas-tests,run-cmis-webservices -Denvironment=default -DrunBugs=false
#
# - name: "Email TAS tests"
# if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip tas\]/) OR commit_message =~ /\[tas\]/
# install: travis_retry travis_wait 40 env REQUIRES_LOCAL_IMAGES=true bash scripts/travis/build.sh
# before_script:
# - ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal.yml
# - ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
# script: travis_wait 30 mvn -B verify -f packaging/tests/tas-email/pom.xml -Pall-tas-tests -Denvironment=default -DrunBugs=false
#
# - name: "WebDAV TAS tests"
# if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip tas\]/) OR commit_message =~ /\[tas\]/
# install: travis_retry travis_wait 40 env REQUIRES_LOCAL_IMAGES=true bash scripts/travis/build.sh
# before_script:
# - ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal.yml
# - ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
# script: travis_wait 30 mvn -B verify -f packaging/tests/tas-webdav/pom.xml -Pall-tas-tests -Denvironment=default -DrunBugs=false
#
# - name: "Integration TAS tests"
# if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip tas\]/) OR commit_message =~ /\[tas\]/
# install: travis_retry travis_wait 40 env REQUIRES_LOCAL_IMAGES=true bash scripts/travis/build.sh
# before_script:
# - ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal.yml
# - ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
# script: travis_wait 30 mvn -B verify -f packaging/tests/tas-integration/pom.xml -Pall-tas-tests -Denvironment=default -DrunBugs=false
#
# - name: "Share Services - ShareServicesTestSuite"
# 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: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)"
# if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip ags\]/) OR commit_message =~ /\[ags\]/
# install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
# script: travis_retry travis_wait 80 mvn -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-postgres -PagsAllTestSuitePt1 -f amps/ags/pom.xml ${LOG_WARN}
#
# - name: "AGS Integration Tests 02 (PostgreSQL)"
# if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip ags\]/) OR commit_message =~ /\[ags\]/
# install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
# script: travis_retry travis_wait 80 mvn -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-postgres -PagsAllTestSuitePt2 -f amps/ags/pom.xml ${LOG_WARN}
#
# - name: "AGS Integration Tests 03 (PostgreSQL)"
# if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip ags\]/) OR commit_message =~ /\[ags\]/
# install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
# script: travis_retry travis_wait 80 mvn -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-postgres -PagsAllTestSuitePt3 -f amps/ags/pom.xml ${LOG_WARN}
#
# - name: "AGS Unit & Integration Tests 04 (PostgreSQL)"
# if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip ags\]/) OR commit_message =~ /\[ags\]/
# install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
# script: travis_retry travis_wait 80 mvn -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-postgres -PagsAllTestSuitePt4 -f amps/ags/pom.xml ${LOG_WARN}
#
# - name: "AGS Unit & Integration Tests 01 (MySQL) "
# if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip ags\]/) OR commit_message =~ /\[ags on MySQL\]/
# install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
# script: travis_retry travis_wait 80 mvn -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-mysql -PagsAllTestSuitePt1 -f amps/ags/pom.xml ${LOG_WARN}
#
# - name: "AGS Integration Tests 02 (MySQL) "
# if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip ags\]/) OR commit_message =~ /\[ags on MySQL\]/
# install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
# script: travis_retry travis_wait 80 mvn -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-mysql -PagsAllTestSuitePt2 -f amps/ags/pom.xml ${LOG_WARN}
#
# - name: "AGS Integration Tests 03 (MySQL) "
# if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip ags\]/) OR commit_message =~ /\[ags\]/
# install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
# script: travis_retry travis_wait 80 mvn -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-mysql -PagsAllTestSuitePt3 -f amps/ags/pom.xml ${LOG_WARN}
#
# - name: "AGS Unit & Integration Tests 04 (MySQL) "
# if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip ags\]/) OR commit_message =~ /\[ags on MySQL\]/
# install: travis_retry travis_wait 40 env REQUIRES_INSTALLED_ARTIFACTS=true bash scripts/travis/build.sh
# script: travis_retry travis_wait 80 mvn -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-mysql -PagsAllTestSuitePt4 -f amps/ags/pom.xml ${LOG_WARN}
#
# - name: "AGS Community Rest API Tests"
# if: (branch =~ /(release\/.*$|master)/ AND commit_message !~ /\[skip ags\]/) OR commit_message =~ /\[ags\]/
# install: travis_retry travis_wait 40 env REQUIRES_LOCAL_IMAGES=true bash scripts/travis/build.sh
# addons:
# artifacts:
# paths:
# - ./amps/ags/rm-automation/rm-automation-community-rest-api/target/reports/rm-automation-community-rest-api.log
# - alfresco.log
# - solr.log
# target_paths: community/${TRAVIS_BUILD_NUMBER}/${TRAVIS_JOB_NAME}
# before_script:
# - ${TAS_SCRIPTS}/start-compose.sh ./amps/ags/rm-community/rm-community-repo/docker-compose.yml
# - ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8080/alfresco"
# script: travis_wait 40 mvn -B test -pl :alfresco-governance-services-automation-community-rest-api -am -DfailIfNoTests=false -Dskip.automationtests=false -Pags
# after_script: bash amps/ags/travis/scripts/getLogs.sh
- name: "Push to Nexus"
stage: release

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-amps</artifactId>
<version>17.41</version>
<version>17.75-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.41</version>
<version>17.75-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.41</version>
<version>17.75-SNAPSHOT</version>
</parent>
<build>

View File

@@ -161,7 +161,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();

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-parent</artifactId>
<version>17.41</version>
<version>17.75-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.41</version>
<version>17.75-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.41</version>
<version>17.75-SNAPSHOT</version>
</parent>
<build>

View File

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

View File

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

View File

@@ -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.41</version>
<version>17.75-SNAPSHOT</version>
</parent>
<dependencies>

View File

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

View File

@@ -146,7 +146,7 @@ public interface NamespaceService extends NamespacePrefixResolver
/** Email Server Application Model Prefix */
static final String EMAILSERVER_MODEL_PREFIX = "emailserver";
/**
* Register a prefix for namespace uri.
*

View File

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

View File

@@ -9,6 +9,6 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>17.41</version>
<version>17.75-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.41</version>
<version>17.75-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>17.41</version>
<version>17.75-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.41</version>
<version>17.75-SNAPSHOT</version>
</parent>
<modules>

View File

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

View File

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

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>17.41</version>
<version>17.75-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.41</version>
<version>17.75-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,102 @@
package org.alfresco.rest.actions.access;
import com.google.gson.Gson;
import org.alfresco.rest.actions.access.pojo.Action;
import org.alfresco.rest.actions.access.pojo.ActionCondition;
import org.alfresco.rest.actions.access.pojo.Rule;
import org.alfresco.utility.model.UserModel;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class AccessRestrictionUtil {
public static final String MAIL_ACTION = "mail";
public static final String ERROR_MESSAGE_FIELD = "message";
public static final String ERROR_MESSAGE_ACCESS_RESTRICTED =
"Only admin or system user is allowed to define uses of or directly execute this action";
private static final String ERROR_MESSAGE_FAILED_TO_SEND_EMAIL = "Failed to send email to:";
public static Map<String, String> createMailParameters(UserModel sender, UserModel recipient) {
Map<String, String> parameterValues = new HashMap<>();
parameterValues.put("from", sender.getEmailAddress());
parameterValues.put("to", recipient.getEmailAddress());
parameterValues.put("subject", "Test");
parameterValues.put("text", "<html>content</html>");
return parameterValues;
}
public static Rule createRuleWithAction(String actionName, Map<String, String> parameterValues) {
Rule rule = new Rule();
rule.setId("");
rule.setTitle("Test rule title");
rule.setDescription("Test rule description");
rule.setRuleType(List.of("inbound"));
rule.setDisabled(false);
rule.setApplyToChildren(false);
rule.setExecuteAsynchronously(false);
Action compositeAction = new Action();
compositeAction.setActionDefinitionName("composite-action");
ActionCondition actionCondition = new ActionCondition();
actionCondition.setConditionDefinitionName("no-condition");
actionCondition.setParameterValues(new HashMap<>());
compositeAction.setConditions(List.of(actionCondition));
Action action = createAction(actionName, parameterValues);
compositeAction.setActions(List.of(action));
rule.setAction(compositeAction);
return rule;
}
public static Action createActionWithParameters(String actionName, Map<String, String> parameterValues) {
Action compositeAction = new Action();
compositeAction.setActionDefinitionName("composite-action");
ActionCondition actionCondition = new ActionCondition();
actionCondition.setConditionDefinitionName("no-condition");
actionCondition.setParameterValues(new HashMap<>());
compositeAction.setConditions(List.of(actionCondition));
Action action = createAction(actionName, parameterValues);
action.setExecuteAsynchronously(false);
compositeAction.setActions(List.of(action));
return action;
}
public static Action createAction(String actionName, Map<String, String> parameterValues) {
Action action = new Action();
action.setActionDefinitionName(actionName);
action.setParameterValues(parameterValues);
return action;
}
public static String mapObjectToJSON(Object object) {
Gson gson = new Gson();
return gson.toJson(object);
}
/**
* Return error message that in fact means that the action has passed access restriction correctly,
* but due to non-configured smtp couldn't send email.
*
* @param userModel
* @return
*/
public static String getExpectedEmailSendFailureMessage(UserModel userModel) {
return ERROR_MESSAGE_FAILED_TO_SEND_EMAIL + userModel.getEmailAddress();
}
}

View File

@@ -0,0 +1,84 @@
package org.alfresco.rest.actions.access;
import org.alfresco.rest.RestTest;
import org.alfresco.rest.core.RestRequest;
import org.alfresco.rest.core.RestResponse;
import org.alfresco.rest.core.RestWrapper;
import org.alfresco.utility.model.UserModel;
import org.json.simple.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.util.Map;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.ERROR_MESSAGE_ACCESS_RESTRICTED;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.ERROR_MESSAGE_FIELD;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.MAIL_ACTION;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.createMailParameters;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.getExpectedEmailSendFailureMessage;
import static org.hamcrest.Matchers.containsString;
public class FormProcAdminAccessRestrictionTest extends RestTest {
private static final String ACTION_FORM_PROCESSOR_ENDPOINT = "alfresco/service/api/action/%s/formprocessor";
private static final String PROPERTY_PREFIX = "prop_";
private UserModel adminUser;
private UserModel testUser;
@Autowired
protected RestWrapper restClient;
@BeforeClass(alwaysRun = true)
public void dataPreparation() throws Exception {
adminUser = dataUser.getAdminUser();
testUser = dataUser.createRandomTestUser();
}
@BeforeMethod(alwaysRun=true)
public void setup() {
restClient.configureRequestSpec()
.setBasePath("")
.addHeader("Content-Type", "application/json");
}
@Test
public void userShouldNotCreateAMailForm() {
restClient.authenticateUser(testUser);
String body = generateBody(createMailParameters(adminUser, testUser));
String endpoint = String.format(ACTION_FORM_PROCESSOR_ENDPOINT, MAIL_ACTION);
RestRequest request = RestRequest.requestWithBody(HttpMethod.POST, body, endpoint);
RestResponse response = restClient.process(request);
response.assertThat().statusCode(HttpStatus.INTERNAL_SERVER_ERROR.value())
.assertThat().body(ERROR_MESSAGE_FIELD, containsString(ERROR_MESSAGE_ACCESS_RESTRICTED));
}
@Test
public void adminShouldCreateAMailForm() {
restClient.authenticateUser(adminUser);
String body = generateBody(createMailParameters(adminUser, testUser));
String endpoint = String.format(ACTION_FORM_PROCESSOR_ENDPOINT, MAIL_ACTION);
RestRequest request = RestRequest.requestWithBody(HttpMethod.POST, body, endpoint);
RestResponse response = restClient.process(request);
response.assertThat().statusCode(HttpStatus.INTERNAL_SERVER_ERROR.value())
.assertThat().body(ERROR_MESSAGE_FIELD, containsString(getExpectedEmailSendFailureMessage(testUser)));
}
private String generateBody(Map<String, String> mailParameters) {
JSONObject json = new JSONObject();
mailParameters.forEach((key, value) -> json.put(PROPERTY_PREFIX + key, value));
return json.toJSONString();
}
}

View File

@@ -0,0 +1,102 @@
package org.alfresco.rest.actions.access;
import org.alfresco.rest.RestTest;
import org.alfresco.rest.actions.access.pojo.Rule;
import org.alfresco.rest.core.RestRequest;
import org.alfresco.rest.core.RestResponse;
import org.alfresco.rest.core.RestWrapper;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FileType;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.UserModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.ERROR_MESSAGE_ACCESS_RESTRICTED;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.ERROR_MESSAGE_FIELD;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.MAIL_ACTION;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.createMailParameters;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.createRuleWithAction;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.mapObjectToJSON;
import static org.hamcrest.Matchers.containsString;
public class RuleAdminAccessRestrictionTest extends RestTest {
private static final String CREATE_RULE_ENDPOINT = "alfresco/service/api/node/workspace/SpacesStore/%s/ruleset/rules";
private UserModel adminUser;
private UserModel testUser;
private FolderModel testFolder;
@Autowired
protected RestWrapper restClient;
@BeforeClass(alwaysRun = true)
public void dataPreparation() throws Exception {
adminUser = dataUser.getAdminUser();
testUser = dataUser.createRandomTestUser();
testSite = dataSite.usingUser(testUser)
.createPublicRandomSite();
testFolder = dataContent.usingUser(testUser)
.usingSite(testSite)
.createFolder();
}
@BeforeMethod(alwaysRun=true)
public void setup() {
restClient.configureRequestSpec().setBasePath("");
}
@Test
public void userShouldNotBeAbleToCreateANewRule() {
restClient.authenticateUser(testUser);
Rule rule = createRuleWithAction(MAIL_ACTION, createMailParameters(adminUser, testUser));
String ruleRequestBody = mapObjectToJSON(rule);
String ruleEndpoint = String.format(CREATE_RULE_ENDPOINT, testFolder.getNodeRef());
RestRequest request = RestRequest.requestWithBody(HttpMethod.POST, ruleRequestBody, ruleEndpoint);
RestResponse response = restClient.process(request);
response.assertThat().statusCode(HttpStatus.INTERNAL_SERVER_ERROR.value())
.assertThat().body(ERROR_MESSAGE_FIELD, containsString(ERROR_MESSAGE_ACCESS_RESTRICTED));
}
@Test
public void adminShouldBeAbleToCreateANewRule() {
restClient.authenticateUser(adminUser);
Rule rule = createRuleWithAction(MAIL_ACTION, createMailParameters(adminUser, testUser));
String ruleRequestBody = mapObjectToJSON(rule);
String ruleEndpoint = String.format(CREATE_RULE_ENDPOINT, testFolder.getNodeRef());
RestRequest request = RestRequest.requestWithBody(HttpMethod.POST, ruleRequestBody, ruleEndpoint);
RestResponse response = restClient.process(request);
response.assertThat().statusCode(HttpStatus.OK.value());
}
@Test
public void userShouldAddAFileToFolderWithMailRule() {
restClient.authenticateUser(adminUser);
Rule rule = createRuleWithAction(MAIL_ACTION, createMailParameters(adminUser, testUser));
String ruleRequestBody = mapObjectToJSON(rule);
String ruleEndpoint = String.format(CREATE_RULE_ENDPOINT, testFolder.getNodeRef());
RestRequest request = RestRequest.requestWithBody(HttpMethod.POST, ruleRequestBody, ruleEndpoint);
RestResponse response = restClient.process(request);
response.assertThat().statusCode(HttpStatus.OK.value());
dataContent.usingUser(testUser)
.usingSite(testSite)
.usingResource(testFolder)
.createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
}
}

View File

@@ -0,0 +1,76 @@
package org.alfresco.rest.actions.access;
import org.alfresco.rest.actions.access.pojo.Action;
import org.alfresco.rest.RestTest;
import org.alfresco.rest.core.RestRequest;
import org.alfresco.rest.core.RestResponse;
import org.alfresco.rest.core.RestWrapper;
import org.alfresco.utility.model.UserModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.ERROR_MESSAGE_ACCESS_RESTRICTED;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.ERROR_MESSAGE_FIELD;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.MAIL_ACTION;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.createActionWithParameters;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.createMailParameters;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.getExpectedEmailSendFailureMessage;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.mapObjectToJSON;
import static org.hamcrest.Matchers.containsString;
public class V0AdminAccessRestrictionTest extends RestTest {
private static final String ACTION_QUEUE_ENDPOINT = "alfresco/service/api/actionQueue?async=false";
private UserModel adminUser;
private UserModel testUser;
@Autowired
protected RestWrapper restClient;
@BeforeClass(alwaysRun = true)
public void dataPreparation() throws Exception {
adminUser = dataUser.getAdminUser();
testUser = dataUser.createRandomTestUser();
testSite = dataSite.usingUser(testUser)
.createPublicRandomSite();
}
@BeforeMethod(alwaysRun=true)
public void setup() {
restClient.configureRequestSpec().setBasePath("");
}
@Test
public void userShouldNotExecuteMailActionQueue() {
restClient.authenticateUser(testUser);
Action action = createActionWithParameters(MAIL_ACTION, createMailParameters(adminUser, testUser));
String actionRequestBody = mapObjectToJSON(action);
RestRequest request = RestRequest.requestWithBody(HttpMethod.POST, actionRequestBody, ACTION_QUEUE_ENDPOINT);
RestResponse response = restClient.process(request);
response.assertThat().statusCode(HttpStatus.INTERNAL_SERVER_ERROR.value())
.assertThat().body(ERROR_MESSAGE_FIELD, containsString(ERROR_MESSAGE_ACCESS_RESTRICTED));
}
@Test
public void adminShouldExecuteMailActionQueue() {
restClient.authenticateUser(adminUser);
Action action = createActionWithParameters(MAIL_ACTION, createMailParameters(adminUser, testUser));
String actionRequestBody = mapObjectToJSON(action);
RestRequest request = RestRequest.requestWithBody(HttpMethod.POST, actionRequestBody, ACTION_QUEUE_ENDPOINT);
RestResponse response = restClient.process(request);
response.assertThat().statusCode(HttpStatus.INTERNAL_SERVER_ERROR.value())
.assertThat().body(ERROR_MESSAGE_FIELD, containsString(getExpectedEmailSendFailureMessage(testUser)));
}
}

View File

@@ -0,0 +1,64 @@
package org.alfresco.rest.actions.access;
import org.alfresco.rest.RestTest;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.UserModel;
import org.springframework.http.HttpStatus;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.alfresco.rest.core.RestWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.ERROR_MESSAGE_ACCESS_RESTRICTED;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.MAIL_ACTION;
import static org.alfresco.rest.actions.access.AccessRestrictionUtil.createMailParameters;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
public class V1AdminAccessRestrictionTest extends RestTest {
private UserModel adminUser;
private UserModel testUser;
private FolderModel testFolder;
@Autowired
protected RestWrapper restClient;
@BeforeClass(alwaysRun = true)
public void dataPreparation() throws Exception {
adminUser = dataUser.getAdminUser();
testUser = dataUser.createRandomTestUser();
testSite = dataSite.usingUser(testUser)
.createPublicRandomSite();
testFolder = dataContent.usingUser(testUser)
.usingSite(testSite)
.createFolder();
}
@Test
public void userShouldNotExecuteMailAction() throws Exception {
restClient.authenticateUser(testUser)
.withCoreAPI()
.usingActions()
.executeAction(MAIL_ACTION, testFolder, createMailParameters(adminUser, testUser));
restClient.onResponse()
.assertThat().statusCode(HttpStatus.INTERNAL_SERVER_ERROR.value())
.assertThat().body("entry.id", nullValue());
restClient.assertLastError().containsSummary(ERROR_MESSAGE_ACCESS_RESTRICTED);
}
@Test
public void adminShouldExecuteMailAction() throws Exception {
restClient.authenticateUser(adminUser)
.withCoreAPI()
.usingActions()
.executeAction(MAIL_ACTION, testFolder, createMailParameters(adminUser, testUser));
restClient.onResponse()
.assertThat().statusCode(HttpStatus.ACCEPTED.value())
.assertThat().body("entry.id", notNullValue());
}
}

View File

@@ -0,0 +1,57 @@
package org.alfresco.rest.actions.access.pojo;
import java.util.List;
import java.util.Map;
public class Action {
private String actionDefinitionName;
private String actionedUponNode;
private List<ActionCondition> conditions;
private List<Action> actions;
private Map<String, String> parameterValues;
private boolean executeAsynchronously;
public void setExecuteAsynchronously(boolean executeAsynchronously) {
this.executeAsynchronously = executeAsynchronously;
}
public String getActionDefinitionName() {
return actionDefinitionName;
}
public void setActionDefinitionName(String actionDefinitionName) {
this.actionDefinitionName = actionDefinitionName;
}
public String getActionedUponNode() {
return actionedUponNode;
}
public void setActionedUponNode(String actionedUponNode) {
this.actionedUponNode = actionedUponNode;
}
public List<ActionCondition> getConditions() {
return conditions;
}
public void setConditions(List<ActionCondition> conditions) {
this.conditions = conditions;
}
public List<Action> getActions() {
return actions;
}
public void setActions(List<Action> actions) {
this.actions = actions;
}
public Map<String, String> getParameterValues() {
return parameterValues;
}
public void setParameterValues(Map<String, String> parameterValues) {
this.parameterValues = parameterValues;
}
}

View File

@@ -0,0 +1,24 @@
package org.alfresco.rest.actions.access.pojo;
import java.util.Map;
public class ActionCondition {
private String conditionDefinitionName;
private Map<String, String> parameterValues;
public String getConditionDefinitionName() {
return conditionDefinitionName;
}
public void setConditionDefinitionName(String conditionDefinitionName) {
this.conditionDefinitionName = conditionDefinitionName;
}
public Map<String, String> getParameterValues() {
return parameterValues;
}
public void setParameterValues(Map<String, String> parameterValues) {
this.parameterValues = parameterValues;
}
}

View File

@@ -0,0 +1,78 @@
package org.alfresco.rest.actions.access.pojo;
import java.util.List;
public class Rule {
private String id;
private String title;
private String description;
private List<String> ruleType;
private boolean executeAsynchronously;
private boolean disabled;
private boolean applyToChildren;
private Action action;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<String> getRuleType() {
return ruleType;
}
public void setRuleType(List<String> ruleType) {
this.ruleType = ruleType;
}
public boolean isExecuteAsynchronously() {
return executeAsynchronously;
}
public void setExecuteAsynchronously(boolean executeAsynchronously) {
this.executeAsynchronously = executeAsynchronously;
}
public boolean isDisabled() {
return disabled;
}
public void setDisabled(boolean disabled) {
this.disabled = disabled;
}
public boolean isApplyToChildren() {
return applyToChildren;
}
public void setApplyToChildren(boolean applyToChildren) {
this.applyToChildren = applyToChildren;
}
public Action getAction() {
return action;
}
public void setAction(Action action) {
this.action = action;
}
}

View File

@@ -0,0 +1,268 @@
/*
* #%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.createActionModel;
import static org.alfresco.rest.rules.RulesTestsUtils.createRuleModel;
import static org.alfresco.utility.constants.UserRole.*;
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.util.List;
import java.util.stream.IntStream;
import org.alfresco.rest.RestTest;
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 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. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void createRule()
{
RestRuleModel ruleModel = createRuleModel("ruleName");
RestRuleModel rule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.createSingleRule(ruleModel);
restClient.assertStatusCodeIs(CREATED);
rule.assertThat().field("id").isNotNull()
.assertThat().field("name").is("ruleName");
}
/** 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 = new RestRuleModel();
ruleModel.setName("");
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 = new RestRuleModel();
// 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");
}
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(createActionModel()));
return restClient.authenticateUser(userWithRole).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
}
}

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,161 @@
/*
* #%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.RestRuleModelsCollection;
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;
@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);
}
/** 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 a rule set by its id. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void getRuleSetById()
{
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);
String ruleSetId = ruleSets.getEntries().get(0).onModel().getId();
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, TestGroup.SANITY })
public void getRuleSetByNonExistingId()
{
STEP("Get the rule set using fake rule set id");
String ruleSetId = "fake-rule-set-id";
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).getRuleSet(ruleSetId);
restClient.assertStatusCodeIs(NOT_FOUND);
}
}

View File

@@ -0,0 +1,217 @@
/*
* #%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.createRuleModel;
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 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;
@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. */
@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()));
}
/** 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 a rule by its id. */
@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());
}
/** 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 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,68 @@
/*
* #%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.util.List;
import java.util.Map;
import org.alfresco.rest.model.RestActionBodyExecTemplateModel;
import org.alfresco.rest.model.RestRuleModel;
public class RulesTestsUtils
{
public static RestRuleModel createRuleModel(String name) {
return createRuleModel(name, List.of(createActionModel()));
}
/**
* 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 createActionModel()
{
RestActionBodyExecTemplateModel restActionModel = new RestActionBodyExecTemplateModel();
restActionModel.setActionDefinitionId("add-features");
restActionModel.setParams(Map.of("aspect-name", "{http://www.alfresco.org/model/audio/1.0}audio", "actionContext", "rule"));
return restActionModel;
}
}

View File

@@ -0,0 +1,201 @@
/*
* #%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.createActionModel;
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. */
@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");
}
/** 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 = new RestRuleModel();
updatedRuleModel.setName("");
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());
}
private RestRuleModel createAndSaveRule(String name)
{
return createAndSaveRule(name, List.of(createActionModel()));
}
/**
* 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.41</version>
<version>17.75-SNAPSHOT</version>
</parent>
<developers>

View File

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

43
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.41</version>
<version>17.75-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Alfresco Community Repo Parent</name>
@@ -53,10 +53,10 @@
<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-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>
@@ -76,7 +76,7 @@
<dependency.xercesImpl.version>2.12.2</dependency.xercesImpl.version>
<dependency.slf4j.version>1.7.35</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>
@@ -85,7 +85,7 @@
<dependency.keycloak.version>15.0.2</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>
@@ -107,20 +107,20 @@
<dependency.jakarta-json-path.version>2.7.0</dependency.jakarta-json-path.version>
<dependency.jakarta-rpc-api.version>1.1.4</dependency.jakarta-rpc-api.version>
<alfresco.googledrive.version>3.2.1.3</alfresco.googledrive.version>
<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.tas-utility.version>3.0.49</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-restapi.version>1.101</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>
@@ -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.41</tag>
<tag>HEAD</tag>
</scm>
<distributionManagement>
@@ -877,6 +877,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 +905,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 +931,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 +940,7 @@
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</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.41</version>
<version>17.75-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
@@ -43,6 +43,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;
@@ -361,18 +362,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

View File

@@ -0,0 +1,61 @@
/*
* #%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.Rule;
import org.alfresco.rest.api.model.rules.RuleSet;
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);
}

View File

@@ -26,10 +26,14 @@
package org.alfresco.rest.api;
import org.alfresco.rest.api.model.Rule;
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;
import java.util.List;
/**
* Folder node rules API.
@@ -41,10 +45,52 @@ public interface Rules
/**
* Get rules for node's and rule set's IDs
*
* @param folderNodeId node ID
* @param ruleSetId rule set ID
* @param paging {@link Paging} information
* @param folderNodeId - folder node ID
* @param ruleSetId - rule set ID
* @param paging - {@link Paging} information
* @return {@link CollectionWithPagingInfo} containing a list page of folder rules
*/
CollectionWithPagingInfo<Rule> getRules(String folderNodeId, String ruleSetId, Paging paging);
/**
* Get 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
* @return {@link Rule} definition
*/
Rule getRuleById(String folderNodeId, String ruleSetId, String ruleId);
/**
* 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.
* @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);
/**
* 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.
* @return The newly updated rule.
*/
Rule updateRuleById(String folderNodeId, String ruleSetId, String ruleId, Rule rule);
/**
* 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

@@ -1,129 +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 org.alfresco.model.ContentModel;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.Rules;
import org.alfresco.rest.api.model.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.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.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;
@Experimental
public class RulesImpl implements Rules
{
private static final String DEFAULT_RULE_SET_ID = "-default-";
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 = validateNode(folderNodeId, ContentModel.TYPE_FOLDER);
if (isNotDefaultId(ruleSetId)) {
final NodeRef ruleSetNodeRef = validateNode(ruleSetId, ContentModel.TYPE_SYSTEM_FOLDER, "rule set");
if (!ruleService.isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef)) {
throw new InvalidArgumentException("Rule set is not associated with folder node!");
}
}
final List<Rule> rules = ruleService.getRules(folderNodeRef).stream()
.map(Rule::from)
.collect(Collectors.toList());
return ListPage.of(rules, paging);
}
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 NodeRef validateNode(final String nodeId, final QName namespaceType)
{
return validateNode(nodeId, namespaceType, null);
}
/**
* Validates if node exists, user have permission to read from it and is of a given type.
*
* @param nodeId - node ID
* @param expectedType - expected type
* @param expectedTypeName - expected type local name
* @return node reference
*/
private NodeRef validateNode(final String nodeId, final QName expectedType, final String expectedTypeName)
{
final NodeRef nodeRef = nodes.validateNode(nodeId);
if (permissionService.hasReadPermission(nodeRef) != AccessStatus.ALLOWED) {
throw new PermissionDeniedException("Cannot read from this node!");
}
final Set<QName> expectedTypes = Set.of(expectedType);
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));
}
return nodeRef;
}
private static boolean isNotDefaultId(final String ruleSetId) {
return !DEFAULT_RULE_SET_ID.equals(ruleSetId);
}
}

View File

@@ -0,0 +1,185 @@
/*
* #%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.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.model.rules.RuleSet;
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.NodeRef;
import org.alfresco.service.cmr.rule.RuleService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName;
/** Responsible for validating nodes when working with rules. */
public class NodeValidator
{
private static final String RULE_SET_EXPECTED_TYPE_NAME = "rule set";
private Nodes nodes;
private RuleService ruleService;
private PermissionService permissionService;
/**
* 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 the user doesn't have the appropriate permission for the folder.
*/
public NodeRef validateFolderNode(final String folderNodeId, boolean requireChangePermission)
{
final NodeRef nodeRef = nodes.validateOrLookupNode(folderNodeId, null);
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!");
}
}
verifyNodeType(nodeRef, ContentModel.TYPE_FOLDER, null);
return nodeRef;
}
/**
* Validates if rule set ID is default, node exists and associated folder node matches.
*
* @param ruleSetId - rule set node ID
* @param associatedFolderNodeRef - folder node ref to check the association
* @return rule set node reference
* @throws InvalidArgumentException in case of not matching associated folder node
*/
public NodeRef validateRuleSetNode(final String ruleSetId, final NodeRef associatedFolderNodeRef)
{
if (RuleSet.isDefaultId(ruleSetId))
{
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))
{
throw new InvalidArgumentException("Rule set is not associated with folder node!");
}
return ruleSetNodeRef;
}
/**
* Validates if rule node exists and associated rule set node matches.
*
* @param ruleId - rule node ID
* @param associatedRuleSetNodeRef - rule set node ref to check the association. Can be null
* @return rule node reference
* @throws InvalidArgumentException in case of not matching associated rule set node
*/
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))
{
throw new InvalidArgumentException("Rule is not associated with rule set node!");
}
return ruleNodeRef;
}
private NodeRef validateNode(final String nodeId, final QName expectedType, final String expectedTypeName)
{
final NodeRef nodeRef = nodes.validateNode(nodeId);
verifyNodeType(nodeRef, expectedType, expectedTypeName);
return nodeRef;
}
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();
throw new InvalidArgumentException(String.format("NodeId of a %s is expected!", expectedTypeLocalName));
}
}
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;
}
}

View File

@@ -0,0 +1,80 @@
/*
* #%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.rest.api.RuleSets;
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.repository.NodeRef;
import org.alfresco.service.cmr.rule.RuleService;
@Experimental
public class RuleSetsImpl implements RuleSets
{
private RuleService ruleService;
private NodeValidator validator;
@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::getId)
.map(RuleSet::of).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 RuleSet.of(ruleSetNode.getId());
}
public void setValidator(NodeValidator validator)
{
this.validator = validator;
}
public void setRuleService(RuleService ruleService)
{
this.ruleService = ruleService;
}
}

View File

@@ -0,0 +1,129 @@
/*
* #%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.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.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;
@Override
public CollectionWithPagingInfo<Rule> getRules(final String folderNodeId, final String ruleSetId, final Paging paging)
{
final NodeRef folderNodeRef = validator.validateFolderNode(folderNodeId, false);
final NodeRef ruleSetNodeRef = validator.validateRuleSetNode(ruleSetId, folderNodeRef);
final boolean isShared = validator.isRuleSetNotNullAndShared(ruleSetNodeRef);
final List<Rule> rules = ruleService.getRules(folderNodeRef).stream()
.map(ruleModel -> Rule.from(ruleModel, isShared))
.collect(Collectors.toList());
return ListPage.of(rules, paging);
}
@Override
public Rule getRuleById(final String folderNodeId, final String ruleSetId, final String ruleId)
{
final NodeRef folderNodeRef = validator.validateFolderNode(folderNodeId, false);
final NodeRef ruleSetNodeRef = validator.validateRuleSetNode(ruleSetId, folderNodeRef);
final NodeRef ruleNodeRef = validator.validateRuleNode(ruleId, ruleSetNodeRef);
return Rule.from(ruleService.getRule(ruleNodeRef), validator.isRuleSetNotNullAndShared(ruleSetNodeRef));
}
@Override
public List<Rule> createRules(final String folderNodeId, final String ruleSetId, final List<Rule> rules)
{
final NodeRef folderNodeRef = validator.validateFolderNode(folderNodeId, true);
// Don't validate the ruleset node if -default- is passed since we may need to create it.
final NodeRef ruleSetNodeRef = (RuleSet.isNotDefaultId(ruleSetId)) ? validator.validateRuleSetNode(ruleSetId, folderNodeRef) : null;
return rules.stream()
.map(rule -> rule.toServiceModel(nodes))
.map(rule -> ruleService.saveRule(folderNodeRef, rule))
.map(rule -> Rule.from(rule, validator.isRuleSetNotNullAndShared(ruleSetNodeRef, folderNodeRef)))
.collect(Collectors.toList());
}
@Override
public Rule updateRuleById(String folderNodeId, String ruleSetId, String ruleId, Rule rule)
{
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);
boolean shared = validator.isRuleSetNotNullAndShared(ruleSetNodeRef, folderNodeRef);
return Rule.from(ruleService.saveRule(folderNodeRef, rule.toServiceModel(nodes)), shared);
}
@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);
}
public void setNodes(Nodes nodes)
{
this.nodes = nodes;
}
public void setRuleService(RuleService ruleService)
{
this.ruleService = ruleService;
}
public void setValidator(NodeValidator validator)
{
this.validator = validator;
}
}

View File

@@ -0,0 +1,170 @@
/*
* #%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.repo.action.executer.SetPropertyValueActionExecuter;
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(), SetPropertyValueActionExecuter.NAME, 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,362 @@
/*
* #%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.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 org.alfresco.service.cmr.repository.NodeRef;
@Experimental
public class Rule
{
private String id;
private String name;
private String description;
private boolean enabled;
private boolean cascade;
private boolean asynchronous;
private boolean shared;
private String errorScript;
private List<RuleTrigger> triggers;
private CompositeCondition conditions;
private List<Action> actions;
/**
* 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, final boolean shared)
{
if (ruleModel == null)
{
return null;
}
final Rule.Builder builder = builder()
.name(ruleModel.getTitle())
.description(ruleModel.getDescription())
.enabled(!ruleModel.getRuleDisabled())
.cascade(ruleModel.isAppliedToChildren())
.asynchronous(ruleModel.getExecuteAsynchronously())
.shared(shared);
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.setAction(Action.toCompositeAction(actions));
return ruleModel;
}
@UniqueId
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
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 isShared()
{
return shared;
}
public void setShared(boolean shared)
{
this.shared = shared;
}
public List<String> getTriggers()
{
if (triggers == null)
{
return null;
}
return triggers.stream().map(RuleTrigger::getValue).collect(Collectors.toList());
}
public void setTriggers(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 + '\'' + ", description='" + description + '\'' + ", enabled=" + enabled + ", cascade=" + cascade
+ ", asynchronous=" + asynchronous + ", shared=" + shared + ", 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 && shared == rule.shared && 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, shared, 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 shared;
private String errorScript;
private List<RuleTrigger> triggers;
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 shared(boolean shared)
{
this.shared = shared;
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.setShared(shared);
rule.setErrorScript(errorScript);
rule.setTriggers(triggers);
rule.setConditions(conditions);
rule.setActions(actions);
return rule;
}
}
}

View File

@@ -0,0 +1,110 @@
/*
* #%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 org.alfresco.service.Experimental;
@Experimental
public class RuleSet
{
public static final String DEFAULT_ID = "-default-";
private String id;
public static RuleSet of(String id)
{
return builder()
.id(id)
.create();
}
public static boolean isNotDefaultId(final String id) {
return !isDefaultId(id);
}
public static boolean isDefaultId(final String id) {
return DEFAULT_ID.equals(id);
}
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
@Override
public String toString()
{
return "RuleSet{" + "id='" + id + '\'' + '}';
}
@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);
}
@Override
public int hashCode()
{
return Objects.hash(id);
}
public static Builder builder()
{
return new Builder();
}
public static class Builder
{
private String id;
public Builder id(String id)
{
this.id = id;
return this;
}
public RuleSet create()
{
final RuleSet ruleSet = new RuleSet();
ruleSet.setId(id);
return ruleSet;
}
}
}

View File

@@ -24,47 +24,38 @@
* #L%
*/
package org.alfresco.rest.api.model;
package org.alfresco.rest.api.model.rules;
import org.alfresco.rest.framework.resource.UniqueId;
import org.alfresco.service.Experimental;
@Experimental
public class Rule
public enum RuleTrigger
{
private String id;
private String name;
INBOUND("inbound"),
UPDATE("update"),
OUTBOUND("outbound");
public static Rule from(final org.alfresco.service.cmr.rule.Rule ruleModel) {
if (ruleModel == null) {
return null;
RuleTrigger(String value)
{
this.value = value;
}
private final String value;
public String getValue()
{
return value;
}
public static RuleTrigger of(final String value)
{
for (RuleTrigger ruleTrigger : values())
{
if (ruleTrigger.value.equals(value)) {
return ruleTrigger;
}
}
final Rule rule = new Rule();
rule.id = ruleModel.getNodeRef().getId();
rule.name = ruleModel.getTitle();
return rule;
}
@UniqueId
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
return null;
}
}

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

@@ -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

@@ -27,8 +27,9 @@
package org.alfresco.rest.api.nodes;
import org.alfresco.rest.api.Rules;
import org.alfresco.rest.api.model.Rule;
import org.alfresco.rest.api.model.rules.Rule;
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;
@@ -38,6 +39,7 @@ import org.alfresco.util.PropertyCheck;
import org.springframework.beans.factory.InitializingBean;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* Folder node's rules.
@@ -45,7 +47,12 @@ import javax.servlet.http.HttpServletResponse;
*/
@Experimental
@RelationshipResource(name = "rules", entityResource = NodeRuleSetsRelation.class, title = "Folder node rules")
public class NodeRulesRelation implements RelationshipResourceAction.Read<Rule>, InitializingBean
public class NodeRulesRelation implements RelationshipResourceAction.Read<Rule>,
RelationshipResourceAction.ReadById<Rule>,
RelationshipResourceAction.Create<Rule>,
RelationshipResourceAction.Update<Rule>,
RelationshipResourceAction.Delete,
InitializingBean
{
private Rules rules;
@@ -57,17 +64,17 @@ public class NodeRulesRelation implements RelationshipResourceAction.Read<Rule>,
}
/**
* List folder node rules for given node's and rule set's IDs as a page.
* List folder rules for given folder node's and rule set's IDs as a page.
*
* - GET /nodes/{folderNodeId}/rulesets/{ruleSetId}/rules
* - GET /nodes/{folderNodeId}/rule-sets/{ruleSetId}/rules
*
* @param folderNodeId - entity resource context for this relationship
* @param parameters - will never be null. Contains i.a. paging information and ruleSetId (relationshipId)
* @return a paged list of folder rules
* @return {@link CollectionWithPagingInfo} containing a page of folder rules
*/
@WebApiDescription(
title = "Get folder node rules",
description = "Returns a paged list of folder rules for given node's and rule set's ID",
description = "Returns a paged list of folder rules for given node's and rule set's IDs",
successStatus = HttpServletResponse.SC_OK
)
@Override
@@ -78,6 +85,99 @@ public class NodeRulesRelation implements RelationshipResourceAction.Read<Rule>,
return rules.getRules(folderNodeId, ruleSetId, parameters.getPaging());
}
/**
* Get single folder rule for given node's, rule set's and rule's IDs.
*
* - GET /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 - will never be null. Contains i.a. ruleId (relationship2Id)
* @return {@link Rule} definition
* @throws RelationshipResourceNotFoundException in case resource was not found
*/
@WebApiDescription(
title="Get folder node rule",
description = "Returns a folder single rule definition for given node's, rule set's and rule's IDs",
successStatus = HttpServletResponse.SC_OK
)
@Override
public Rule readById(String folderNodeId, String ruleSetId, Parameters parameters) throws RelationshipResourceNotFoundException
{
final String ruleId = parameters.getRelationship2Id();
return rules.getRuleById(folderNodeId, ruleSetId, ruleId);
}
/**
* 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);
}
/**
* 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);
}
/**
* 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)
{
this.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,9 +850,38 @@
</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" />
</bean>
<bean class="org.alfresco.rest.api.nodes.NodeRulesRelation">
<property name="rules" ref="Rules" />
</bean>
<bean id="ruleSets" class="org.alfresco.rest.api.impl.rules.RuleSetsImpl">
<property name="validator" ref="nodeValidator" />
<property name="ruleService" 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 class="org.alfresco.rest.api.nodes.NodeRuleSetsRelation">
<property name="ruleSets" ref="RuleSets" />
</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" />
</bean>
@@ -866,10 +895,6 @@
</property>
</bean>
<bean class="org.alfresco.rest.api.nodes.NodeRulesRelation">
<property name="rules" ref="Rules" />
</bean>
<bean id="publicapi.mimeTypePropertyLookup" class="org.alfresco.rest.api.lookups.MimeTypePropertyLookup">
<property name="serviceRegistry" ref="ServiceRegistry"/>
<property name="supported">

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

@@ -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,53 @@
/*
* #%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.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,
NodeValidatorTest.class,
RuleTest.class,
ActionTest.class,
SimpleConditionTest.class,
CompositeConditionTest.class
})
public class RulesUnitTests
{
}

View File

@@ -1,193 +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.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 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-node-id";
private static final String RULE_SET_ID = "dummy-rule-set-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);
@Mock
private Nodes nodes;
@Mock
private PermissionService permissionService;
@Mock
private RuleService ruleService;
@InjectMocks
private RulesImpl rules;
@Before
@Override
public void setUp() throws Exception
{
MockitoAnnotations.openMocks(this);
given(nodes.validateNode(eq(FOLDER_NODE_ID))).willReturn(folderNodeRef);
given(nodes.validateNode(eq(RULE_SET_ID))).willReturn(ruleSetNodeRef);
given(nodes.nodeMatches(any(), any(), any())).willReturn(true);
given(permissionService.hasReadPermission(any())).willReturn(AccessStatus.ALLOWED);
}
@Test
public void testGetRules()
{
final Paging paging = Paging.DEFAULT;
given(ruleService.isRuleSetAssociatedWithFolder(any(), any())).willReturn(true);
// when
final CollectionWithPagingInfo<Rule> rulesPage = rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging);
then(nodes).should().validateNode(eq(FOLDER_NODE_ID));
then(nodes).should().validateNode(eq(RULE_SET_ID));
then(nodes).should().nodeMatches(eq(folderNodeRef), any(), isNull());
then(nodes).should().nodeMatches(eq(ruleSetNodeRef), any(), isNull());
then(nodes).shouldHaveNoMoreInteractions();
then(permissionService).should().hasReadPermission(eq(folderNodeRef));
then(permissionService).should().hasReadPermission(eq(ruleSetNodeRef));
then(permissionService).shouldHaveNoMoreInteractions();
then(ruleService).should().isRuleSetAssociatedWithFolder(eq(ruleSetNodeRef), eq(folderNodeRef));
then(ruleService).should().getRules(eq(folderNodeRef));
then(ruleService).shouldHaveNoMoreInteractions();
assertThat(rulesPage)
.isNotNull()
.extracting(CollectionWithPagingInfo::getCollection)
.isNotNull();
}
@Test
public void testGetRulesForDefaultRuleSet()
{
final String defaultRuleSetId = "-default-";
final Paging paging = Paging.DEFAULT;
// when
final CollectionWithPagingInfo<Rule> rulesPage = rules.getRules(FOLDER_NODE_ID, defaultRuleSetId, paging);
then(nodes).should().validateNode(eq(FOLDER_NODE_ID));
then(nodes).should().nodeMatches(eq(folderNodeRef), any(), isNull());
then(nodes).shouldHaveNoMoreInteractions();
then(permissionService).should().hasReadPermission(eq(folderNodeRef));
then(permissionService).shouldHaveNoMoreInteractions();
then(ruleService).should().getRules(eq(folderNodeRef));
then(ruleService).shouldHaveNoMoreInteractions();
assertThat(rulesPage)
.isNotNull()
.extracting(CollectionWithPagingInfo::getCollection)
.isNotNull();
}
@Test
public void testGetRulesForNotExistingFolderNode()
{
final Paging paging = Paging.DEFAULT;
given(nodes.nodeMatches(eq(folderNodeRef), any(), any())).willReturn(false);
// when
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
() -> rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging));
then(ruleService).shouldHaveNoInteractions();
}
@Test
public void testGetRulesForNotExistingRuleSetNode()
{
final Paging paging = Paging.DEFAULT;
given(nodes.nodeMatches(eq(folderNodeRef), any(), any())).willReturn(true);
given(nodes.nodeMatches(eq(ruleSetNodeRef), any(), any())).willReturn(false);
// when
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
() -> rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging));
then(ruleService).shouldHaveNoInteractions();
}
@Test
public void testGetRulesForNotAssociatedRuleSetToFolder()
{
final Paging paging = Paging.DEFAULT;
given(ruleService.isRuleSetAssociatedWithFolder(any(), any())).willReturn(false);
// when
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
() -> rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging));
then(ruleService).should().isRuleSetAssociatedWithFolder(eq(ruleSetNodeRef), eq(folderNodeRef));
then(ruleService).shouldHaveNoMoreInteractions();
}
@Test
public void testGetRulesWithoutReadPermission()
{
final Paging paging = Paging.DEFAULT;
given(permissionService.hasReadPermission(any())).willReturn(AccessStatus.DENIED);
// when
assertThatExceptionOfType(PermissionDeniedException.class).isThrownBy(
() -> rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging));
then(ruleService).shouldHaveNoInteractions();
}
}

View File

@@ -0,0 +1,379 @@
/*
* #%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 java.util.Set;
import org.alfresco.rest.api.Nodes;
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.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.rule.RuleService;
import org.alfresco.service.cmr.security.PermissionService;
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 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);
@Mock
private Nodes nodesMock;
@Mock
private PermissionService permissionServiceMock;
@Mock
private RuleService ruleServiceMock;
@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 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 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();
}
}

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 java.util.Collections.emptyList;
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.rest.api.model.rules.RuleSet;
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.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 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 RULE_SET_NODE = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_SET_ID);
private static final Paging PAGING = Paging.DEFAULT;
@InjectMocks
private RuleSetsImpl ruleSets;
@Mock
private NodeValidator nodeValidatorMock;
@Mock
private RuleService ruleServiceMock;
@Before
@Override
public void setUp()
{
MockitoAnnotations.openMocks(this);
given(nodeValidatorMock.validateFolderNode(eq(FOLDER_ID), anyBoolean())).willReturn(FOLDER_NODE);
//given(nodeValidatorMock.validateFolderNode(eq(RULE_SET_ID), anyBoolean())).willReturn(RULE_SET_NODE);
given(nodeValidatorMock.validateRuleSetNode(RULE_SET_ID, FOLDER_NODE)).willReturn(RULE_SET_NODE);
given(ruleServiceMock.getRuleSetNode(FOLDER_NODE)).willReturn(RULE_SET_NODE);
}
@Test
public void testGetRuleSets()
{
// Call the method under test.
CollectionWithPagingInfo<RuleSet> actual = ruleSets.getRuleSets(FOLDER_ID, null, 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(RuleSet.of(RULE_SET_ID));
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, null, 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, null);
then(nodeValidatorMock).should().validateFolderNode(FOLDER_ID, false);
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, FOLDER_NODE);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
assertEquals(RuleSet.of(RULE_SET_ID), actual);
}
}

View File

@@ -0,0 +1,614 @@
/*
* #%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.model.rules.RuleSet.DEFAULT_ID;
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.anyBoolean;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import junit.framework.TestCase;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.model.rules.CompositeCondition;
import org.alfresco.rest.api.model.rules.Rule;
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.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
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.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.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
@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;
private static final Action action = new ActionImpl(folderNodeRef, "actionId", "actionDefinitionName");
@Mock
private Nodes nodesMock;
@Mock
private NodeValidator nodeValidatorMock;
@Mock
private RuleService ruleServiceMock;
@InjectMocks
private RulesImpl rules;
@Before
@Override
public void setUp() throws Exception
{
MockitoAnnotations.openMocks(this);
given(nodeValidatorMock.validateFolderNode(any(), anyBoolean())).willReturn(folderNodeRef);
given(nodeValidatorMock.validateRuleSetNode(any(), any())).willReturn(ruleSetNodeRef);
given(nodeValidatorMock.validateRuleNode(any(), any())).willReturn(ruleNodeRef);
}
@Test
public void testGetRules()
{
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(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, false);
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, folderNodeRef);
then(nodeValidatorMock).should().isRuleSetNotNullAndShared(ruleSetNodeRef);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().getRules(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 testGetRules_emptyResult()
{
given(ruleServiceMock.getRules(any())).willReturn(emptyList());
// when
final CollectionWithPagingInfo<Rule> rulesPage = rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging);
then(ruleServiceMock).should().getRules(folderNodeRef);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
assertThat(rulesPage)
.isNotNull()
.extracting(CollectionWithPagingInfo::getCollection)
.isNotNull()
.extracting(Collection::isEmpty)
.isEqualTo(true);
}
@Test
public void testGetRules_invalidFolder()
{
for (Exception exception : folderValidationExceptions())
{
Mockito.reset(nodeValidatorMock);
given(nodeValidatorMock.validateFolderNode(any(), anyBoolean())).willThrow(exception);
// when
assertThatExceptionOfType(exception.getClass()).isThrownBy(
() -> rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging));
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, false);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
}
}
@Test
public void testGetRules_invalidRuleSet()
{
for (Exception exception : ruleSetValidationExceptions())
{
Mockito.reset(nodeValidatorMock);
given(nodeValidatorMock.validateFolderNode(any(), anyBoolean())).willReturn(folderNodeRef);
given(nodeValidatorMock.validateRuleSetNode(any(), any())).willThrow(exception);
// when
assertThatExceptionOfType(exception.getClass()).isThrownBy(
() -> rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging));
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, false);
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, folderNodeRef);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
}
}
@Test
public void testGetRuleById()
{
given(ruleServiceMock.getRule(any())).willReturn(createRule(RULE_ID));
// when
final Rule rule = rules.getRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID);
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, false);
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, folderNodeRef);
then(nodeValidatorMock).should().validateRuleNode(RULE_ID, ruleSetNodeRef);
then(nodeValidatorMock).should().isRuleSetNotNullAndShared(ruleSetNodeRef);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(nodesMock).shouldHaveNoInteractions();
then(ruleServiceMock).should().getRule(ruleNodeRef);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
assertThat(rule)
.isNotNull()
.extracting(Rule::getId)
.isEqualTo(RULE_ID);
}
@Test
public void testGetRuleById_invalidFolder()
{
for (Exception exception : folderValidationExceptions())
{
Mockito.reset(nodeValidatorMock);
given(nodeValidatorMock.validateFolderNode(any(), anyBoolean())).willThrow(exception);
// when
assertThatExceptionOfType(exception.getClass()).isThrownBy(
() -> rules.getRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID));
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, false);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
}
}
@Test
public void testGetRuleById_invalidRuleSet()
{
for (Exception exception : ruleSetValidationExceptions())
{
Mockito.reset(nodeValidatorMock);
given(nodeValidatorMock.validateFolderNode(any(), anyBoolean())).willReturn(folderNodeRef);
given(nodeValidatorMock.validateRuleSetNode(any(), any())).willThrow(exception);
// when
assertThatExceptionOfType(exception.getClass()).isThrownBy(
() -> rules.getRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID));
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, false);
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, folderNodeRef);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
}
}
@Test
public void testGetRuleById_invalidRule()
{
for (Exception exception : ruleValidationExceptions())
{
Mockito.reset(nodeValidatorMock);
given(nodeValidatorMock.validateFolderNode(any(), anyBoolean())).willReturn(folderNodeRef);
given(nodeValidatorMock.validateRuleSetNode(any(), any())).willReturn(ruleSetNodeRef);
given(nodeValidatorMock.validateRuleNode(any(), any())).willThrow(exception);
// when
assertThatExceptionOfType(exception.getClass()).isThrownBy(
() -> rules.getRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID));
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, false);
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, folderNodeRef);
then(nodeValidatorMock).should().validateRuleNode(RULE_ID, ruleSetNodeRef);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
}
}
/** Create a single rule. */
@Test
public void testCreateRules()
{
Rule ruleBody = mock(Rule.class);
List<Rule> ruleList = List.of(ruleBody);
org.alfresco.service.cmr.rule.Rule serviceRuleBody = mock(org.alfresco.service.cmr.rule.Rule.class);
given(ruleBody.toServiceModel(nodesMock)).willReturn(serviceRuleBody);
org.alfresco.service.cmr.rule.Rule serviceRule = mock(org.alfresco.service.cmr.rule.Rule.class);
given(ruleServiceMock.saveRule(folderNodeRef, serviceRuleBody)).willReturn(serviceRule);
given(serviceRule.getNodeRef()).willReturn(ruleNodeRef);
given(serviceRule.getAction()).willReturn(action);
// when
List<Rule> actual = rules.createRules(folderNodeRef.getId(), ruleSetNodeRef.getId(), ruleList);
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true);
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, folderNodeRef);
then(nodeValidatorMock).should().isRuleSetNotNullAndShared(ruleSetNodeRef, folderNodeRef);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(nodeValidatorMock).should().isRuleSetNotNullAndShared(ruleSetNodeRef, folderNodeRef);
then(ruleServiceMock).should().saveRule(folderNodeRef, ruleBody.toServiceModel(nodesMock));
then(ruleServiceMock).shouldHaveNoMoreInteractions();
List<Rule> expected = List.of(Rule.from(serviceRule, false));
assertThat(actual).isEqualTo(expected);
}
/** Check that when passing the default rule set then we don't perform any validation around the rule set node. */
@Test
public void testCreateRules_defaultRuleSet()
{
Rule ruleBody = mock(Rule.class);
List<Rule> ruleList = List.of(ruleBody);
org.alfresco.service.cmr.rule.Rule serviceRuleBody = mock(org.alfresco.service.cmr.rule.Rule.class);
given(ruleBody.toServiceModel(nodesMock)).willReturn(serviceRuleBody);
org.alfresco.service.cmr.rule.Rule serviceRule = mock(org.alfresco.service.cmr.rule.Rule.class);
given(ruleServiceMock.saveRule(folderNodeRef, serviceRuleBody)).willReturn(serviceRule);
given(serviceRule.getNodeRef()).willReturn(ruleNodeRef);
given(serviceRule.getAction()).willReturn(action);
// when
List<Rule> actual = rules.createRules(folderNodeRef.getId(), DEFAULT_ID, ruleList);
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true);
then(nodeValidatorMock).should().isRuleSetNotNullAndShared(null, folderNodeRef);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().saveRule(folderNodeRef, ruleBody.toServiceModel(nodesMock));
then(ruleServiceMock).shouldHaveNoMoreInteractions();
List<Rule> expected = List.of(Rule.from(serviceRule, false));
assertThat(actual).isEqualTo(expected);
}
@Test
public void testCreateRules_emptyRuleList()
{
List<Rule> ruleList = emptyList();
// when
List<Rule> actual = rules.createRules(folderNodeRef.getId(), ruleSetNodeRef.getId(), ruleList);
then(ruleServiceMock).shouldHaveNoInteractions();
assertThat(actual).isEqualTo(emptyList());
}
/** Create three rules in a single call and check they are all passed to the RuleService. */
@Test
public void testCreateRules_createMultipleRules()
{
List<Rule> ruleBodyList = new ArrayList<>();
List<Rule> expected = new ArrayList<>();
for (String ruleId : List.of("A", "B", "C"))
{
Rule ruleBody = mock(Rule.class);
ruleBodyList.add(ruleBody);
org.alfresco.service.cmr.rule.Rule serviceRuleBody = mock(org.alfresco.service.cmr.rule.Rule.class);
given(ruleBody.toServiceModel(nodesMock)).willReturn(serviceRuleBody);
org.alfresco.service.cmr.rule.Rule serviceRule = mock(org.alfresco.service.cmr.rule.Rule.class);
given(ruleServiceMock.saveRule(folderNodeRef, serviceRuleBody)).willReturn(serviceRule);
NodeRef ruleNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, ruleId);
given(serviceRule.getNodeRef()).willReturn(ruleNodeRef);
given(serviceRule.getAction()).willReturn(action);
expected.add(Rule.from(serviceRule, false));
}
// when
List<Rule> actual = rules.createRules(folderNodeRef.getId(), ruleSetNodeRef.getId(), ruleBodyList);
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true);
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, folderNodeRef);
then(nodeValidatorMock).should(times(ruleBodyList.size())).isRuleSetNotNullAndShared(ruleSetNodeRef, folderNodeRef);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
for (Rule ruleBody : ruleBodyList)
{
then(ruleServiceMock).should().saveRule(folderNodeRef, ruleBody.toServiceModel(nodesMock));
}
then(ruleServiceMock).shouldHaveNoMoreInteractions();
assertThat(actual).isEqualTo(expected);
}
@Test
public void testCreateRules_invalidFolder()
{
for (Exception exception : folderValidationExceptions())
{
Mockito.reset(nodeValidatorMock);
given(nodeValidatorMock.validateFolderNode(any(), anyBoolean())).willThrow(exception);
// when
assertThatExceptionOfType(exception.getClass()).isThrownBy(
() -> rules.createRules(folderNodeRef.getId(), ruleSetNodeRef.getId(), emptyList()));
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
}
}
@Test
public void testCreateRules_invalidRuleSet()
{
for (Exception exception : ruleSetValidationExceptions())
{
Mockito.reset(nodeValidatorMock);
given(nodeValidatorMock.validateFolderNode(any(), anyBoolean())).willReturn(folderNodeRef);
given(nodeValidatorMock.validateRuleSetNode(any(), any())).willThrow(exception);
// when
assertThatExceptionOfType(exception.getClass()).isThrownBy(
() -> rules.createRules(folderNodeRef.getId(), ruleSetNodeRef.getId(), emptyList()));
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true);
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, folderNodeRef);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
}
}
/** Check that we can update a rule. */
@Test
public void testUpdateRuleById()
{
Rule ruleBody = mock(Rule.class);
given(nodeValidatorMock.isRuleSetNotNullAndShared(any(), any())).willReturn(true);
org.alfresco.service.cmr.rule.Rule serviceRuleBody = mock(org.alfresco.service.cmr.rule.Rule.class);
given(ruleBody.toServiceModel(nodesMock)).willReturn(serviceRuleBody);
org.alfresco.service.cmr.rule.Rule serviceRule = mock(org.alfresco.service.cmr.rule.Rule.class);
given(ruleServiceMock.saveRule(folderNodeRef, serviceRuleBody)).willReturn(serviceRule);
given(serviceRule.getNodeRef()).willReturn(ruleNodeRef);
given(serviceRule.getAction()).willReturn(action);
// when
Rule updatedRule = rules.updateRuleById(folderNodeRef.getId(), ruleSetNodeRef.getId(), RULE_ID, ruleBody);
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true);
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, folderNodeRef);
then(nodeValidatorMock).should().validateRuleNode(RULE_ID, ruleSetNodeRef);
then(nodeValidatorMock).should().isRuleSetNotNullAndShared(ruleSetNodeRef, folderNodeRef);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().saveRule(folderNodeRef, serviceRuleBody);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
Rule expected = Rule.builder().id(RULE_ID)
.enabled(true)
.shared(true)
.triggers(emptyList())
.conditions(CompositeCondition.builder().inverted(false).create())
.create();
assertThat(updatedRule).isEqualTo(expected);
}
@Test
public void testUpdateRuleById_invalidFolder()
{
for (Exception exception : folderValidationExceptions())
{
Mockito.reset(nodeValidatorMock);
given(nodeValidatorMock.validateFolderNode(any(), anyBoolean())).willThrow(exception);
// when
assertThatExceptionOfType(exception.getClass()).isThrownBy(
() -> rules.updateRuleById(folderNodeRef.getId(), ruleSetNodeRef.getId(), RULE_ID, mock(Rule.class)));
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
}
}
@Test
public void testUpdateRuleById_invalidRuleSet()
{
for (Exception exception : ruleSetValidationExceptions())
{
Mockito.reset(nodeValidatorMock);
given(nodeValidatorMock.validateFolderNode(any(), anyBoolean())).willReturn(folderNodeRef);
given(nodeValidatorMock.validateRuleSetNode(any(), any())).willThrow(exception);
// when
assertThatExceptionOfType(exception.getClass()).isThrownBy(
() -> rules.updateRuleById(folderNodeRef.getId(), ruleSetNodeRef.getId(), RULE_ID, mock(Rule.class)));
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true);
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, folderNodeRef);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
}
}
@Test
public void testUpdateRuleById_invalidRule()
{
for (Exception exception : ruleValidationExceptions())
{
Mockito.reset(nodeValidatorMock);
given(nodeValidatorMock.validateFolderNode(any(), anyBoolean())).willReturn(folderNodeRef);
given(nodeValidatorMock.validateRuleSetNode(any(), any())).willReturn(ruleSetNodeRef);
given(nodeValidatorMock.validateRuleNode(any(), any())).willThrow(exception);
// when
assertThatExceptionOfType(exception.getClass()).isThrownBy(
() -> rules.updateRuleById(folderNodeRef.getId(), ruleSetNodeRef.getId(), RULE_ID, mock(Rule.class)));
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true);
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, folderNodeRef);
then(nodeValidatorMock).should().validateRuleNode(RULE_ID, ruleSetNodeRef);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
}
}
@Test
public void testDeleteRuleById() {
org.alfresco.service.cmr.rule.Rule rule = createRule(RULE_ID);
given(ruleServiceMock.getRule(any())).willReturn(rule);
//when
rules.deleteRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID);
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true);
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, folderNodeRef);
then(nodeValidatorMock).should().validateRuleNode(RULE_ID, ruleSetNodeRef);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(nodesMock).shouldHaveNoInteractions();
then(ruleServiceMock).should().getRule(ruleNodeRef);
then(ruleServiceMock).should().removeRule(folderNodeRef, rule);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
}
@Test
public void testDeleteRuleById_invalidFolder()
{
for (Exception exception : folderValidationExceptions())
{
Mockito.reset(nodeValidatorMock);
given(nodeValidatorMock.validateFolderNode(any(), anyBoolean())).willThrow(exception);
// when
assertThatExceptionOfType(exception.getClass()).isThrownBy(
() -> rules.deleteRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID));
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
}
}
@Test
public void testDeleteRuleById_invalidRuleSet()
{
for (Exception exception : ruleSetValidationExceptions())
{
Mockito.reset(nodeValidatorMock);
given(nodeValidatorMock.validateFolderNode(any(), anyBoolean())).willReturn(folderNodeRef);
given(nodeValidatorMock.validateRuleSetNode(any(), any())).willThrow(exception);
// when
assertThatExceptionOfType(exception.getClass()).isThrownBy(
() -> rules.deleteRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID));
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true);
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, folderNodeRef);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
}
}
@Test
public void testDeleteRuleById_invalidRule()
{
for (Exception exception : ruleValidationExceptions())
{
Mockito.reset(nodeValidatorMock);
given(nodeValidatorMock.validateFolderNode(any(), anyBoolean())).willReturn(folderNodeRef);
given(nodeValidatorMock.validateRuleSetNode(any(), any())).willReturn(ruleSetNodeRef);
given(nodeValidatorMock.validateRuleNode(any(), any())).willThrow(exception);
// when
assertThatExceptionOfType(exception.getClass()).isThrownBy(
() -> rules.deleteRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID));
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true);
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, folderNodeRef);
then(nodeValidatorMock).should().validateRuleNode(RULE_ID, ruleSetNodeRef);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).shouldHaveNoInteractions();
}
}
private static org.alfresco.service.cmr.rule.Rule createRule(final String id) {
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, id);
final org.alfresco.service.cmr.rule.Rule rule = new org.alfresco.service.cmr.rule.Rule();
rule.setNodeRef(nodeRef);
rule.setRuleType("ruleType");
rule.setAction(action);
return rule;
}
private static List<Exception> folderValidationExceptions()
{
return List.of(
new EntityNotFoundException(FOLDER_NODE_ID),
new InvalidArgumentException(),
new PermissionDeniedException()
);
}
private static List<Exception> ruleSetValidationExceptions()
{
return List.of(
new EntityNotFoundException(RULE_SET_ID),
new InvalidArgumentException(),
new RelationshipResourceNotFoundException(RULE_SET_ID, "fake-relationship-id")
);
}
private static List<Exception> ruleValidationExceptions()
{
return List.of(
new EntityNotFoundException(RULE_ID),
new InvalidArgumentException(),
new RelationshipResourceNotFoundException(RULE_ID, "fake-relationship-id")
);
}
}

View File

@@ -0,0 +1,79 @@
/*
* #%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 static org.alfresco.repo.action.executer.SetPropertyValueActionExecuter.PARAM_PROPERTY;
import static org.alfresco.repo.action.executer.SetPropertyValueActionExecuter.PARAM_VALUE;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.junit.Test;
@Experimental
public class ActionTest
{
private static final String ACTION_DEFINITION_NAME = "actionDefName";
private static final Map<String, Serializable> parameters = new HashMap<>();
static
{
parameters.put(PARAM_PROPERTY, "propertyName");
parameters.put(PARAM_VALUE, "propertyValue");
}
@Test
public void testFrom()
{
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "ruleId");
final org.alfresco.service.cmr.action.Action actionModel = new ActionImpl(nodeRef, "actionId", ACTION_DEFINITION_NAME, parameters);
final Action expectedAction = Action.builder().actionDefinitionId(ACTION_DEFINITION_NAME).params(parameters).create();
final Action actualAction = Action.from(actionModel);
assertThat(actualAction).isNotNull().usingRecursiveComparison().isEqualTo(expectedAction);
}
@Test
public void testFromActionModelWithNullValues()
{
final org.alfresco.service.cmr.action.Action actionModel = new ActionImpl(null, null, null);
final Action expectedAction = Action.builder().params(Collections.emptyMap()).create();
final Action actualAction = Action.from(actionModel);
assertThat(actualAction).isNotNull().usingRecursiveComparison().isEqualTo(expectedAction);
}
}

View File

@@ -0,0 +1,180 @@
/*
* #%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 static org.assertj.core.api.Assertions.assertThat;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.action.ActionConditionImpl;
import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.action.ActionCondition;
import org.junit.Test;
@Experimental
public class CompositeConditionTest
{
@Test
public void testFrom()
{
final List<ActionCondition> actionConditions = List.of(
createActionCondition("value1"),
createActionCondition("value2", true),
createActionCondition("value3")
);
final CompositeCondition expectedCompositeCondition = createCompositeCondition(List.of(
createCompositeCondition(false, List.of(
createSimpleCondition("value1"),
createSimpleCondition("value3")
)),
createCompositeCondition(true, List.of(
createSimpleCondition("value2")
))
));
// when
final CompositeCondition actualCompositeCondition = CompositeCondition.from(actionConditions);
assertThat(actualCompositeCondition).isNotNull().usingRecursiveComparison().isEqualTo(expectedCompositeCondition);
}
@Test
public void testFromEmptyList()
{
final List<ActionCondition> actionConditions = Collections.emptyList();
final CompositeCondition expectedCompositeCondition = CompositeCondition.builder().create();
// when
final CompositeCondition actualCompositeCondition = CompositeCondition.from(actionConditions);
assertThat(actualCompositeCondition).isNotNull().usingRecursiveComparison().isEqualTo(expectedCompositeCondition);
}
@Test
public void testFromNullValue()
{
// when
final CompositeCondition actualCompositeCondition = CompositeCondition.from(null);
assertThat(actualCompositeCondition).isNull();
}
@Test
public void testFromListContainingNull()
{
final List<ActionCondition> actionConditions = new ArrayList<>();
actionConditions.add(null);
final CompositeCondition expectedCompositeCondition = CompositeCondition.builder().create();
// when
final CompositeCondition actualCompositeCondition = CompositeCondition.from(actionConditions);
assertThat(actualCompositeCondition).isNotNull().usingRecursiveComparison().isEqualTo(expectedCompositeCondition);
}
@Test
public void testOfSimpleConditions()
{
final List<SimpleCondition> simpleConditions = List.of(SimpleCondition.builder().field("field").comparator("comparator").parameter("param").create());
final boolean inverted = true;
final ConditionOperator conditionOperator = ConditionOperator.OR;
final CompositeCondition expectedCondition = createCompositeCondition(inverted, conditionOperator, null, simpleConditions);
// when
final CompositeCondition actualCompositeCondition = CompositeCondition.ofSimpleConditions(simpleConditions, inverted, conditionOperator);
assertThat(actualCompositeCondition).isNotNull().usingRecursiveComparison().isEqualTo(expectedCondition);
}
@Test
public void testOfEmptySimpleConditions()
{
// when
final CompositeCondition actualCompositeCondition = CompositeCondition.ofSimpleConditions(Collections.emptyList(), false, ConditionOperator.AND);
assertThat(actualCompositeCondition).isNull();
}
@Test
public void testOfNullSimpleConditions()
{
// when
final CompositeCondition actualCompositeCondition = CompositeCondition.ofSimpleConditions(null, false, ConditionOperator.AND);
assertThat(actualCompositeCondition).isNull();
}
private static ActionCondition createActionCondition(final String value)
{
return createActionCondition(value, false);
}
private static ActionCondition createActionCondition(final String value, final boolean inverted)
{
final ActionCondition actionCondition = new ActionConditionImpl("fake-id", ComparePropertyValueEvaluator.NAME);
actionCondition.setInvertCondition(inverted);
final Map<String, Serializable> parameterValues = new HashMap<>();
parameterValues.put(ComparePropertyValueEvaluator.PARAM_CONTENT_PROPERTY, "content-property");
parameterValues.put(ComparePropertyValueEvaluator.PARAM_OPERATION, "operation");
parameterValues.put(ComparePropertyValueEvaluator.PARAM_VALUE, value);
actionCondition.setParameterValues(parameterValues);
return actionCondition;
}
private static SimpleCondition createSimpleCondition(final String value) {
return SimpleCondition.builder()
.field("content-property")
.comparator("operation")
.parameter(value)
.create();
}
private static CompositeCondition createCompositeCondition(final List<CompositeCondition> compositeConditions) {
return createCompositeCondition(false, ConditionOperator.AND, compositeConditions, null);
}
private static CompositeCondition createCompositeCondition(final boolean inverted, final List<SimpleCondition> simpleConditions) {
return createCompositeCondition(inverted, ConditionOperator.AND, null, simpleConditions);
}
private static CompositeCondition createCompositeCondition(final boolean inverted, final ConditionOperator conditionOperator,
final List<CompositeCondition> compositeConditions, final List<SimpleCondition> simpleConditions) {
return CompositeCondition.builder()
.inverted(inverted)
.booleanMode(conditionOperator)
.compositeConditions(compositeConditions)
.simpleConditions(simpleConditions)
.create();
}
}

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.model.rules;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Collections;
import java.util.List;
import org.alfresco.repo.action.ActionConditionImpl;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.repo.action.executer.ScriptActionExecuter;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ActionCondition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.rule.RuleType;
import org.junit.Test;
@Experimental
public class RuleTest
{
private static final String RULE_ID = "fake-rule-id";
private static final String RULE_NAME = "rule name";
private static final String RULE_DESCRIPTION = "rule description";
private static final boolean RULE_ENABLED = true;
private static final boolean RULE_CASCADE = true;
private static final boolean RULE_ASYNC = true;
private static final boolean RULE_SHARED = true;
private static final String ERROR_SCRIPT = "error-script-ref";
@Test
public void testFrom()
{
final org.alfresco.service.cmr.rule.Rule ruleModel = createRuleModel();
final Rule expectedRule = createRuleWithDefaultValues();
// when
final Rule actualRule = Rule.from(ruleModel, RULE_SHARED);
assertThat(actualRule).isNotNull().usingRecursiveComparison().isEqualTo(expectedRule);
}
@Test
public void testFromRuleModelWithNullValues()
{
final org.alfresco.service.cmr.rule.Rule ruleModel = new org.alfresco.service.cmr.rule.Rule();
final Rule expectedRule = Rule.builder().enabled(true).create();
// when
final Rule actualRule = Rule.from(ruleModel, false);
assertThat(actualRule).isNotNull().usingRecursiveComparison().isEqualTo(expectedRule);
}
private static org.alfresco.service.cmr.rule.Rule createRuleModel() {
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_ID);
final org.alfresco.service.cmr.rule.Rule ruleModel = new org.alfresco.service.cmr.rule.Rule(nodeRef);
ruleModel.setTitle(RULE_NAME);
ruleModel.setDescription(RULE_DESCRIPTION);
ruleModel.setRuleDisabled(!RULE_ENABLED);
ruleModel.applyToChildren(RULE_CASCADE);
ruleModel.setExecuteAsynchronously(RULE_ASYNC);
ruleModel.setRuleTypes(List.of(RuleType.INBOUND, RuleType.UPDATE));
final Action compensatingAction = new ActionImpl(nodeRef, "compensatingActionId", "compensatingActionDefName");
compensatingAction.setParameterValue(ScriptActionExecuter.PARAM_SCRIPTREF, ERROR_SCRIPT);
final ActionCondition actionCondition = new ActionConditionImpl("actionConditionId", "actionConditionDefName");
final Action action = new ActionImpl(nodeRef, "actionId", "actionDefName");
action.setCompensatingAction(compensatingAction);
action.addActionCondition(actionCondition);
ruleModel.setAction(action);
return ruleModel;
}
private static Rule createRuleWithDefaultValues() {
return Rule.builder()
.id(RULE_ID)
.name(RULE_NAME)
.description(RULE_DESCRIPTION)
.enabled(RULE_ENABLED)
.cascade(RULE_CASCADE)
.asynchronous(RULE_ASYNC)
.shared(RULE_SHARED)
.triggers(List.of(RuleTrigger.INBOUND, RuleTrigger.UPDATE))
.errorScript(ERROR_SCRIPT)
.conditions(CompositeCondition.from(Collections.emptyList()))
.create();
}
}

View File

@@ -0,0 +1,213 @@
/*
* #%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 static org.assertj.core.api.Assertions.assertThat;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.alfresco.repo.action.ActionConditionImpl;
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.junit.Test;
@Experimental
public class SimpleConditionTest
{
private static List<TestData> getTestData() {
return List.of(
TestData.of(ComparePropertyValueEvaluator.NAME),
TestData.of(CompareMimeTypeEvaluator.NAME),
TestData.of(HasAspectEvaluator.NAME),
TestData.of(HasChildEvaluator.NAME),
TestData.of(HasTagEvaluator.NAME),
TestData.of(HasVersionHistoryEvaluator.NAME),
TestData.of(InCategoryEvaluator.NAME),
TestData.of(IsSubTypeEvaluator.NAME),
TestData.of(NoConditionEvaluator.NAME, true),
TestData.of("fake-definition-name", true),
TestData.of("", true),
TestData.of(null, true)
);
}
@Test
public void testFrom()
{
for (TestData testData : getTestData())
{
final ActionCondition actionCondition = createActionCondition(testData.actionDefinitionName);
// when
final SimpleCondition actualSimpleCondition = SimpleCondition.from(actionCondition);
assertThat(Objects.isNull(actualSimpleCondition)).isEqualTo(testData.isNullResult);
if (!testData.isNullResult)
{
assertThat(actualSimpleCondition.getField()).isNotEmpty();
assertThat(actualSimpleCondition.getComparator()).isNotEmpty();
assertThat(actualSimpleCondition.getParameter()).isNotEmpty();
}
}
}
@Test
public void testFromNullValue()
{
// when
final SimpleCondition actualSimpleCondition = SimpleCondition.from(null);
assertThat(actualSimpleCondition).isNull();
}
@Test
public void testFromActionConditionWithoutDefinitionName()
{
final ActionCondition actionCondition = new ActionConditionImpl("fake-id", null, createParameterValues());
// when
final SimpleCondition actualSimpleCondition = SimpleCondition.from(actionCondition);
assertThat(actualSimpleCondition).isNull();
}
@Test
public void testFromActionConditionWithoutParameterValues()
{
final ActionCondition actionCondition = new ActionConditionImpl("fake-id", "fake-def-name", null);
// when
final SimpleCondition actualSimpleCondition = SimpleCondition.from(actionCondition);
assertThat(actualSimpleCondition).isNull();
}
@Test
public void testListOf()
{
final List<ActionCondition> actionConditions = List.of(
createActionCondition(ComparePropertyValueEvaluator.NAME),
createActionCondition(CompareMimeTypeEvaluator.NAME)
);
final List<SimpleCondition> expectedSimpleConditions = List.of(
SimpleCondition.builder().field("content-property").comparator("operation").parameter("value").create(),
SimpleCondition.builder().field("property").comparator("equals").parameter("value").create()
);
// when
final List<SimpleCondition> actualSimpleConditions = SimpleCondition.listOf(actionConditions);
assertThat(actualSimpleConditions)
.isNotNull()
.containsExactlyElementsOf(expectedSimpleConditions);
}
@Test
public void testListOfEmptyActionConditions()
{
final List<SimpleCondition> actualSimpleConditions = SimpleCondition.listOf(Collections.emptyList());
assertThat(actualSimpleConditions).isNull();
}
@Test
public void testListOfNullActionConditions()
{
final List<SimpleCondition> actualSimpleConditions = SimpleCondition.listOf(null);
assertThat(actualSimpleConditions).isNull();
}
@Test
public void testListOfActionConditionsContainingNull()
{
final List<ActionCondition> actionConditions = new ArrayList<>();
actionConditions.add(null);
final List<SimpleCondition> actualSimpleConditions = SimpleCondition.listOf(actionConditions);
assertThat(actualSimpleConditions).isNotNull().isEmpty();
}
private static ActionCondition createActionCondition(final String actionDefinitionName)
{
return new ActionConditionImpl("fake-id", actionDefinitionName, createParameterValues());
}
private static Map<String, Serializable> createParameterValues() {
final Map<String, Serializable> parameterValues = new HashMap<>();
parameterValues.put(ComparePropertyValueEvaluator.PARAM_CONTENT_PROPERTY, "content-property");
parameterValues.put(HasChildEvaluator.PARAM_ASSOC_TYPE, "assoc-type");
parameterValues.put(ComparePropertyValueEvaluator.PARAM_PROPERTY, "property");
parameterValues.put(ComparePropertyValueEvaluator.PARAM_OPERATION, "operation");
parameterValues.put(ComparePropertyValueEvaluator.PARAM_VALUE, "value");
parameterValues.put(HasAspectEvaluator.PARAM_ASPECT, "aspect");
parameterValues.put(HasChildEvaluator.PARAM_ASSOC_NAME, "assoc-name");
parameterValues.put(HasTagEvaluator.PARAM_TAG, "tag");
parameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_ASPECT, "category-aspect");
parameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_VALUE, "category-value");
parameterValues.put(IsSubTypeEvaluator.PARAM_TYPE, "type");
return parameterValues;
}
private static class TestData
{
String actionDefinitionName;
boolean isNullResult;
public TestData(String actionDefinitionName, boolean isNullResult)
{
this.actionDefinitionName = actionDefinitionName;
this.isNullResult = isNullResult;
}
public static TestData of(String actionDefinitionName) {
return new TestData(actionDefinitionName, false);
}
public static TestData of(String actionDefinitionName, boolean isNullResult) {
return new TestData(actionDefinitionName, isNullResult);
}
}
}

View File

@@ -30,7 +30,7 @@ import junit.framework.TestCase;
import org.alfresco.rest.api.Rules;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rest.framework.resource.parameters.Params;
import org.alfresco.rest.framework.tests.core.ParamsExtender;
import org.alfresco.service.Experimental;
import org.junit.Before;
import org.junit.Test;
@@ -50,9 +50,10 @@ public class NodeRulesRelationTest extends TestCase
private static final String FOLDER_NODE_ID = "dummy-node-id";
private static final String RULE_SET_ID = "dummy-rule-set-id";
private static final String RULE_ID = "dummy-rule-id";
@Mock
private Rules rules;
private Rules rulesMock;
@InjectMocks
private NodeRulesRelation nodeRulesRelation;
@@ -68,13 +69,34 @@ public class NodeRulesRelationTest extends TestCase
public void testReadAll()
{
final Paging paging = Paging.DEFAULT;
final Params.RecognizedParams params = new Params.RecognizedParams(null, paging, null, null, null, null, null, null, false);
final Parameters parameters = Params.valueOf(FOLDER_NODE_ID, RULE_SET_ID, params, null, null);
final Parameters parameters = ParamsExtender.valueOf(paging, FOLDER_NODE_ID, RULE_SET_ID, null);
// when
nodeRulesRelation.readAll(FOLDER_NODE_ID, parameters);
then(rules).should().getRules(eq(FOLDER_NODE_ID), eq(RULE_SET_ID), eq(paging));
then(rules).shouldHaveNoMoreInteractions();
then(rulesMock).should().getRules(eq(FOLDER_NODE_ID), eq(RULE_SET_ID), eq(paging));
then(rulesMock).shouldHaveNoMoreInteractions();
}
}
@Test
public void testReadById()
{
final Parameters parameters = ParamsExtender.valueOf(null, FOLDER_NODE_ID, RULE_SET_ID, RULE_ID);
// when
nodeRulesRelation.readById(FOLDER_NODE_ID, RULE_SET_ID, parameters);
then(rulesMock).should().getRuleById(eq(FOLDER_NODE_ID), eq(RULE_SET_ID), eq(RULE_ID));
then(rulesMock).shouldHaveNoMoreInteractions();
}
@Test
public void testDeleteById() {
final Parameters parameters = ParamsExtender.valueOf(null, FOLDER_NODE_ID, RULE_SET_ID, RULE_ID);
// when
nodeRulesRelation.delete(FOLDER_NODE_ID, RULE_SET_ID, parameters);
then(rulesMock).should().deleteRuleById(eq(FOLDER_NODE_ID), eq(RULE_SET_ID), eq(RULE_ID));
then(rulesMock).shouldHaveNoMoreInteractions();
}
}

View File

@@ -1,34 +1,30 @@
/*
* #%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.rest.api.tests;
import org.apache.chemistry.opencmis.server.impl.atompub.CmisAtomPubServlet;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.webapp.WebAppContext;
/**
* Manages an embedded jetty server, hooking it up to the repository spring context and providing
* authenticated, tenant-based access through the tenant servlet.
@@ -42,15 +38,4 @@ public class EnterpriseJettyComponent extends PublicApiJettyComponent
{
super(port, contextPath, configLocations, classLocations);
}
@Override
protected void configureWebAppContext(WebAppContext webAppContext)
{
super.configureWebAppContext(webAppContext);
// the tenant servlet with alfresco managed authentication
ServletHolder servletHolder = new ServletHolder(CmisAtomPubServlet.class);
servletHolder.setInitParameter("callContextHandler", "org.apache.chemistry.opencmis.server.shared.BasicAuthCallContextHandler");
webAppContext.addServlet(servletHolder, "/cmisatom/*");
}
}

View File

@@ -123,7 +123,7 @@ public class ModulePackagesApiTest extends AbstractBaseApiTest
assertNotNull(response);
assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode());
assertEquals("no-cache", response.getHeaders().get("Cache-Control"));
assertEquals("application/json;charset=UTF-8", response.getHeaders().get("Content-Type"));
assertEquals("application/json;charset=utf-8", response.getHeaders().get("Content-Type"));
PublicApiClient.ExpectedErrorResponse errorResponse = RestApiUtil.parseErrorResponse(response.getJsonResponse());
assertNotNull(errorResponse);

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.rest.api.tests;
import org.alfresco.repo.web.util.AbstractJettyComponent;
@@ -48,63 +48,16 @@ public class PublicApiJettyComponent extends AbstractJettyComponent
@Override
protected void configureWebAppContext(WebAppContext webAppContext)
{
// ServletContext servletContext = webAppContext.getServletContext();
// the tenant servlet with alfresco managed authentication
ServletHolder servletHolder = new ServletHolder(PublicApiWebScriptServlet.class);
servletHolder.setInitParameter("authenticator", "publicapi.authenticator");
webAppContext.addServlet(servletHolder, "/" + publicApiServletName + "/*");
// DependencyInjectedFilter apiFilter = (DependencyInjectedFilter)getApplicationContext().getBean("publicAPICMISFilter");
// BeanProxyFilter filter = new BeanProxyFilter(servletContext, apiFilter);
// FilterHolder filterHolder = new FilterHolder(filter);
// webAppContext.addFilter(filterHolder, "/" + publicApiServletName + "/*", null);
// the tenant servlet with alfresco managed authentication
servletHolder = new ServletHolder(CmisAtomPubServlet.class);
servletHolder.setInitParameter("callContextHandler", "org.apache.chemistry.opencmis.server.shared.BasicAuthCallContextHandler");
webAppContext.addServlet(servletHolder, "/cmisatom/*");
webAppContext.addServlet(servletHolder, "/cmisatom/*");
}
// private static class BeanProxyFilter implements Filter
// {
// private DependencyInjectedFilter filter;
// private ServletContext context;
//
// private BeanProxyFilter(ServletContext context, DependencyInjectedFilter filter)
// {
// this.context = context;
// this.filter = filter;
// }
//
// /**
// * Initialize the filter.
// *
// * @param args
// * FilterConfig
// * @throws ServletException
// * the servlet exception
// * @exception ServletException
// */
// public void init(FilterConfig args) throws ServletException
// {
// }
//
// /* (non-Javadoc)
// * @see javax.servlet.Filter#destroy()
// */
// public void destroy()
// {
// this.filter = null;
// }
//
// /* (non-Javadoc)
// * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
// */
// public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
// ServletException
// {
// this.filter.doFilter(this.context, request, response, chain);
// }
// }
}

View File

@@ -303,7 +303,7 @@ public class SharedLinkApiTest extends AbstractBaseApiTest
assertArrayEquals(file1_originalBytes, response.getResponseAsBytes());
Map<String, String> responseHeaders = response.getHeaders();
assertNotNull(responseHeaders);
assertEquals(file1_MimeType+";charset=UTF-8", responseHeaders.get("Content-Type"));
assertEquals(file1_MimeType+";charset=utf-8", responseHeaders.get("Content-Type"));
assertNotNull(responseHeaders.get("Expires"));
assertEquals("attachment; filename=\"" + fileName1 + "\"; filename*=UTF-8''" + fileName1 + "", responseHeaders.get("Content-Disposition"));
String lastModifiedHeader = responseHeaders.get(LAST_MODIFIED_HEADER);
@@ -319,7 +319,7 @@ public class SharedLinkApiTest extends AbstractBaseApiTest
assertArrayEquals(file1_originalBytes, response.getResponseAsBytes());
responseHeaders = response.getHeaders();
assertNotNull(responseHeaders);
assertEquals(file1_MimeType+";charset=UTF-8", responseHeaders.get("Content-Type"));
assertEquals(file1_MimeType+";charset=utf-8", responseHeaders.get("Content-Type"));
assertNotNull(responseHeaders.get(LAST_MODIFIED_HEADER));
assertNotNull(responseHeaders.get("Expires"));
assertNull(responseHeaders.get("Content-Disposition"));
@@ -330,7 +330,7 @@ public class SharedLinkApiTest extends AbstractBaseApiTest
assertArrayEquals(content2Text.getBytes(), response.getResponseAsBytes());
responseHeaders = response.getHeaders();
assertNotNull(responseHeaders);
assertEquals(file2_MimeType+";charset=ISO-8859-1", responseHeaders.get("Content-Type"));
assertEquals(file2_MimeType+";charset=iso-8859-1", responseHeaders.get("Content-Type"));
assertNotNull(responseHeaders.get("Expires"));
assertNotNull(responseHeaders.get(LAST_MODIFIED_HEADER));
assertEquals("attachment; filename=\"" + fileName2 + "\"; filename*=UTF-8''" + fileName2 + "", responseHeaders.get("Content-Disposition"));
@@ -392,7 +392,7 @@ public class SharedLinkApiTest extends AbstractBaseApiTest
assertTrue(response.getResponseAsBytes().length > 0);
responseHeaders = response.getHeaders();
assertNotNull(responseHeaders);
assertEquals(MimetypeMap.MIMETYPE_IMAGE_PNG+";charset=UTF-8", responseHeaders.get("Content-Type"));
assertEquals(MimetypeMap.MIMETYPE_IMAGE_PNG+";charset=utf-8", responseHeaders.get("Content-Type"));
assertNotNull(responseHeaders.get(LAST_MODIFIED_HEADER));
assertNotNull(responseHeaders.get("Expires"));
String docName = "doclib";
@@ -405,7 +405,7 @@ public class SharedLinkApiTest extends AbstractBaseApiTest
assertTrue(response.getResponseAsBytes().length > 0);
responseHeaders = response.getHeaders();
assertNotNull(responseHeaders);
assertEquals(MimetypeMap.MIMETYPE_IMAGE_PNG+";charset=UTF-8", responseHeaders.get("Content-Type"));
assertEquals(MimetypeMap.MIMETYPE_IMAGE_PNG+";charset=utf-8", responseHeaders.get("Content-Type"));
assertNotNull(responseHeaders.get("Expires"));
assertNull(responseHeaders.get("Content-Disposition"));
lastModifiedHeader = responseHeaders.get(LAST_MODIFIED_HEADER);
@@ -816,7 +816,7 @@ public class SharedLinkApiTest extends AbstractBaseApiTest
assertArrayEquals(file1_originalBytes, response.getResponseAsBytes());
Map<String, String> responseHeaders = response.getHeaders();
assertNotNull(responseHeaders);
assertEquals(file1_MimeType + ";charset=UTF-8", responseHeaders.get("Content-Type"));
assertEquals(file1_MimeType + ";charset=utf-8", responseHeaders.get("Content-Type"));
assertNotNull(responseHeaders.get("Expires"));
assertEquals("attachment; filename=\"" + fileName1 + "\"; filename*=UTF-8''" + fileName1 + "", responseHeaders.get("Content-Disposition"));
String lastModifiedHeader = responseHeaders.get(LAST_MODIFIED_HEADER);
@@ -832,7 +832,7 @@ public class SharedLinkApiTest extends AbstractBaseApiTest
assertArrayEquals(file1_originalBytes, response.getResponseAsBytes());
responseHeaders = response.getHeaders();
assertNotNull(responseHeaders);
assertEquals(file1_MimeType + ";charset=UTF-8", responseHeaders.get("Content-Type"));
assertEquals(file1_MimeType + ";charset=utf-8", responseHeaders.get("Content-Type"));
assertNotNull(responseHeaders.get(LAST_MODIFIED_HEADER));
assertNotNull(responseHeaders.get("Expires"));
assertNull(responseHeaders.get("Content-Disposition"));
@@ -888,7 +888,7 @@ public class SharedLinkApiTest extends AbstractBaseApiTest
assertTrue(response.getResponseAsBytes().length > 0);
responseHeaders = response.getHeaders();
assertNotNull(responseHeaders);
assertEquals(MimetypeMap.MIMETYPE_IMAGE_PNG + ";charset=UTF-8", responseHeaders.get("Content-Type"));
assertEquals(MimetypeMap.MIMETYPE_IMAGE_PNG + ";charset=utf-8", responseHeaders.get("Content-Type"));
assertNotNull(responseHeaders.get(LAST_MODIFIED_HEADER));
assertNotNull(responseHeaders.get("Expires"));
String docName = "doclib";
@@ -901,7 +901,7 @@ public class SharedLinkApiTest extends AbstractBaseApiTest
assertTrue(response.getResponseAsBytes().length > 0);
responseHeaders = response.getHeaders();
assertNotNull(responseHeaders);
assertEquals(MimetypeMap.MIMETYPE_IMAGE_PNG + ";charset=UTF-8", responseHeaders.get("Content-Type"));
assertEquals(MimetypeMap.MIMETYPE_IMAGE_PNG + ";charset=utf-8", responseHeaders.get("Content-Type"));
assertNotNull(responseHeaders.get("Expires"));
assertNull(responseHeaders.get("Content-Disposition"));
lastModifiedHeader = responseHeaders.get(LAST_MODIFIED_HEADER);

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2020 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
@@ -43,29 +43,33 @@ import org.springframework.extensions.webscripts.WebScriptRequest;
public class ParamsExtender extends Params
{
private ParamsExtender(String entityId, String relationshipId, Object passedIn, InputStream stream, String addressedProperty, RecognizedParams recognizedParams)
private ParamsExtender(String entityId, String relationshipId, String relationship2Id, Object passedIn, InputStream stream, String addressedProperty, RecognizedParams recognizedParams)
{
super(null,entityId, relationshipId, null, passedIn, stream, addressedProperty, recognizedParams, null, mock(WebScriptRequest.class));
super(null,entityId, relationshipId, relationship2Id, passedIn, stream, addressedProperty, recognizedParams, null, mock(WebScriptRequest.class));
}
public static Params valueOf(Map<String, BeanPropertiesFilter> rFilter, String entityId)
{
return new ParamsExtender(entityId, null, null, null, null, new Params.RecognizedParams(null, null, null, rFilter, null, null, null, null, false));
return new ParamsExtender(entityId, null, null, null, null, null, new Params.RecognizedParams(null, null, null, rFilter, null, null, null, null, false));
}
public static Params valueOf(boolean includeSource, String entityId)
{
return new ParamsExtender(entityId, null, null, null, null, new Params.RecognizedParams(null, null, null, null, null, null, null, null, includeSource));
return new ParamsExtender(entityId, null, null, null, null, null, new Params.RecognizedParams(null, null, null, null, null, null, null, null, includeSource));
}
public static Params valueOf(Paging paging, String entityId)
{
return new ParamsExtender(entityId, null, null, null, null, new Params.RecognizedParams(null, paging, null, null, null, null, null, null, false));
return new ParamsExtender(entityId, null, null, null, null, null, new Params.RecognizedParams(null, paging, null, null, null, null, null, null, false));
}
public static Params valueOf(Map<String, String[]> params)
{
return new ParamsExtender(null, null, null, null, null, new Params.RecognizedParams(params, null, null, null, null, null, null, null, false));
return new ParamsExtender(null, null, null, null, null, null, new Params.RecognizedParams(params, null, null, null, null, null, null, null, false));
}
public static Params valueOf(Paging paging, String entityId, String relationshipId, String relationship2Id)
{
return new ParamsExtender(entityId, relationshipId, relationship2Id, null, null, null, new Params.RecognizedParams(null, paging, null, null, null, null, null, null, false));
}
}

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>17.41</version>
<version>17.75-SNAPSHOT</version>
</parent>
<dependencies>
@@ -732,6 +732,11 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-transform-model</artifactId>

View File

@@ -101,8 +101,8 @@ public abstract class ActionAccessRestrictionAbstractBase implements ActionAcces
if (context != null)
{
return Stream.of(
getConfigKey(context, actionName),
getConfigKey(context));
getConfigKey(actionName, context),
getConfigKey(actionName));
}
return Stream.of(getConfigKey(actionName));
}

View File

@@ -25,6 +25,15 @@
*/
package org.alfresco.repo.rule;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.repo.action.ActionModel;
@@ -40,6 +49,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.TransactionListener;
import org.alfresco.repo.transaction.TransactionalResourceHelper;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.action.ActionServiceException;
@@ -64,15 +74,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.ParameterCheck;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Rule service implementation.
* <p>
@@ -744,62 +745,63 @@ public class RuleServiceImpl
}
@Override
public void saveRule(NodeRef nodeRef, Rule rule)
public Rule saveRule(NodeRef nodeRef, Rule rule)
{
checkForLinkedRules(nodeRef);
if (this.permissionService.hasPermission(nodeRef, PermissionService.CHANGE_PERMISSIONS) == AccessStatus.ALLOWED)
{
disableRules();
try
{
if (this.nodeService.exists(nodeRef) == false)
{
throw new RuleServiceException("The node does not exist.");
}
NodeRef ruleNodeRef = rule.getNodeRef();
if (ruleNodeRef == null)
{
if (this.nodeService.hasAspect(nodeRef, RuleModel.ASPECT_RULES) == false)
{
// Add the actionable aspect
this.nodeService.addAspect(nodeRef, RuleModel.ASPECT_RULES, null);
}
// Create the action node
ruleNodeRef = this.nodeService.createNode(
getSavedRuleFolderRef(nodeRef),
ContentModel.ASSOC_CONTAINS,
QName.createQName(RuleModel.RULE_MODEL_URI, ASSOC_NAME_RULES_PREFIX + GUID.generate()),
RuleModel.TYPE_RULE).getChildRef();
// Set the rule node reference and the owning node reference
rule.setNodeRef(ruleNodeRef);
}
// Update the properties of the rule
this.nodeService.setProperty(ruleNodeRef, ContentModel.PROP_TITLE, rule.getTitle());
this.nodeService.setProperty(ruleNodeRef, ContentModel.PROP_DESCRIPTION, rule.getDescription());
this.nodeService.setProperty(ruleNodeRef, RuleModel.PROP_RULE_TYPE, (Serializable)rule.getRuleTypes());
this.nodeService.setProperty(ruleNodeRef, RuleModel.PROP_APPLY_TO_CHILDREN, rule.isAppliedToChildren());
this.nodeService.setProperty(ruleNodeRef, RuleModel.PROP_EXECUTE_ASYNC, rule.getExecuteAsynchronously());
this.nodeService.setProperty(ruleNodeRef, RuleModel.PROP_DISABLED, rule.getRuleDisabled());
// Save the rule's action
saveAction(ruleNodeRef, rule);
}
finally
{
enableRules();
// Drop the rules from the cache
nodeRulesCache.remove(nodeRef);
}
}
else
if (this.permissionService.hasPermission(nodeRef, PermissionService.CHANGE_PERMISSIONS) != AccessStatus.ALLOWED)
{
throw new RuleServiceException("Insufficient permissions to save a rule.");
}
disableRules();
try
{
if (this.nodeService.exists(nodeRef) == false)
{
throw new RuleServiceException("The node does not exist.");
}
NodeRef ruleNodeRef = rule.getNodeRef();
if (ruleNodeRef == null)
{
if (this.nodeService.hasAspect(nodeRef, RuleModel.ASPECT_RULES) == false)
{
// Add the actionable aspect
this.nodeService.addAspect(nodeRef, RuleModel.ASPECT_RULES, null);
}
// Create the action node
ruleNodeRef = this.nodeService.createNode(
getSavedRuleFolderRef(nodeRef),
ContentModel.ASSOC_CONTAINS,
QName.createQName(RuleModel.RULE_MODEL_URI, ASSOC_NAME_RULES_PREFIX + GUID.generate()),
RuleModel.TYPE_RULE).getChildRef();
// Set the rule node reference and the owning node reference
rule.setNodeRef(ruleNodeRef);
}
// Update the properties of the rule
String title = rule.getTitle();
ParameterCheck.mandatoryString("Rule name", title);
this.nodeService.setProperty(ruleNodeRef, ContentModel.PROP_TITLE, title);
this.nodeService.setProperty(ruleNodeRef, ContentModel.PROP_DESCRIPTION, rule.getDescription());
this.nodeService.setProperty(ruleNodeRef, RuleModel.PROP_RULE_TYPE, (Serializable)rule.getRuleTypes());
this.nodeService.setProperty(ruleNodeRef, RuleModel.PROP_APPLY_TO_CHILDREN, rule.isAppliedToChildren());
this.nodeService.setProperty(ruleNodeRef, RuleModel.PROP_EXECUTE_ASYNC, rule.getExecuteAsynchronously());
this.nodeService.setProperty(ruleNodeRef, RuleModel.PROP_DISABLED, rule.getRuleDisabled());
// Save the rule's action
saveAction(ruleNodeRef, rule);
}
finally
{
enableRules();
// Drop the rules from the cache
nodeRulesCache.remove(nodeRef);
}
return rule;
}
@Override
@@ -860,10 +862,7 @@ public class RuleServiceImpl
{
// Get the action definition from the rule
Action action = rule.getAction();
if (action == null)
{
throw new RuleServiceException("An action must be specified when defining a rule.");
}
ParameterCheck.mandatory("Rule action", action);
// Get the current action node reference
NodeRef actionNodeRef = null;
@@ -900,10 +899,9 @@ public class RuleServiceImpl
{
checkForLinkedRules(nodeRef);
if (this.permissionService.hasPermission(nodeRef, PermissionService.CHANGE_PERMISSIONS) == AccessStatus.ALLOWED)
if (permissionService.hasPermission(nodeRef, PermissionService.CHANGE_PERMISSIONS) == AccessStatus.ALLOWED)
{
if (this.nodeService.exists(nodeRef) == true &&
this.nodeService.hasAspect(nodeRef, RuleModel.ASPECT_RULES) == true)
if (nodeService.exists(nodeRef) && nodeService.hasAspect(nodeRef, RuleModel.ASPECT_RULES))
{
disableRules(nodeRef);
try
@@ -911,7 +909,7 @@ public class RuleServiceImpl
NodeRef ruleNodeRef = rule.getNodeRef();
if (ruleNodeRef != null)
{
this.nodeService.removeChild(getSavedRuleFolderRef(nodeRef), ruleNodeRef);
nodeService.removeChild(getSavedRuleFolderRef(nodeRef), ruleNodeRef);
}
}
finally
@@ -934,7 +932,7 @@ public class RuleServiceImpl
}
}
this.nodeService.removeAspect(nodeRef, RuleModel.ASPECT_RULES);
nodeService.removeAspect(nodeRef, RuleModel.ASPECT_RULES);
}
}
// Drop the rules from the cache
@@ -944,8 +942,8 @@ public class RuleServiceImpl
{
throw new RuleServiceException("Insufficient permissions to remove a rule.");
}
}
}
/**
* Checks if rules are linked and throws an exception if they are.
*
@@ -1594,7 +1592,7 @@ public class RuleServiceImpl
public List<NodeRef> getLinkedFromRuleNodes(NodeRef nodeRef)
{
List<NodeRef> result = new ArrayList<NodeRef>();
if (nodeService.hasAspect(nodeRef, RuleModel.ASPECT_RULES) == true)
{
ChildAssociationRef assoc = getSavedRuleFolderAssoc(nodeRef);
@@ -1614,13 +1612,48 @@ public class RuleServiceImpl
}
@Override
public boolean isRuleSetAssociatedWithFolder(final NodeRef ruleSetNodeRef, final NodeRef folderNodeRef) {
return findAssociatedParents(ruleSetNodeRef, RuleModel.ASSOC_RULE_FOLDER).stream()
.map(ChildAssociationRef::getParentRef)
.anyMatch(folderNodeRef::equals);
@Experimental
public NodeRef getRuleSetNode(final NodeRef folderNodeRef)
{
return runtimeNodeService.getChildAssocs(folderNodeRef, RuleModel.ASSOC_RULE_FOLDER, RuleModel.ASSOC_RULE_FOLDER).stream()
.map(ChildAssociationRef::getChildRef)
.findFirst()
.orElse(null);
}
private List<ChildAssociationRef> findAssociatedParents(final NodeRef nodeRef, final QNamePattern pattern) {
return runtimeNodeService.getParentAssocs(nodeRef, pattern, pattern);
@Override
@Experimental
public boolean isRuleSetAssociatedWithFolder(final NodeRef ruleSetNodeRef, final NodeRef folderNodeRef)
{
return isChildOf(ruleSetNodeRef, RuleModel.ASSOC_RULE_FOLDER, folderNodeRef);
}
@Override
@Experimental
public boolean isRuleAssociatedWithRuleSet(final NodeRef ruleNodeRef, final NodeRef ruleSetNodeRef)
{
return isChildOf(ruleNodeRef, null, ruleSetNodeRef);
}
private boolean isChildOf(final NodeRef childNodeRef, final QNamePattern associationType, final NodeRef parentNodeRef)
{
final List<ChildAssociationRef> associations;
if (associationType == null) {
associations = runtimeNodeService.getParentAssocs(childNodeRef);
} else {
associations = runtimeNodeService.getParentAssocs(childNodeRef, associationType, associationType);
}
return associations.stream()
.map(ChildAssociationRef::getParentRef)
.anyMatch(parentNodeRef::equals);
}
@Override
@Experimental
public boolean isRuleSetShared(final NodeRef ruleSetNodeRef)
{
return runtimeNodeService.getParentAssocs(ruleSetNodeRef).stream()
.anyMatch(association -> !association.isPrimary());
}
}

View File

@@ -28,6 +28,7 @@ package org.alfresco.service.cmr.rule;
import java.util.List;
import org.alfresco.service.Auditable;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -175,7 +176,7 @@ public interface RuleService
* @return a list of the rules associated with the node
*/
@Auditable(parameters = {"nodeRef"})
public List<Rule> getRules(NodeRef nodeRef);
public List<Rule> getRules(NodeRef nodeRef);
/**
* Get the rules associated with an actionable node.
@@ -234,8 +235,8 @@ public interface RuleService
* @param rule Rule
*/
@Auditable(parameters = {"nodeRef", "rule"})
public void saveRule(NodeRef nodeRef, Rule rule);
public Rule saveRule(NodeRef nodeRef, Rule rule);
/**
*
* @param nodeRef NodeRef
@@ -331,12 +332,44 @@ public interface RuleService
public List<NodeRef> getLinkedFromRuleNodes(NodeRef nodeRef);
/**
* Check if rule set's associated parent is equal to folder node.
* Get rule set node associated with folder
*
* @param folderNodeRef - folder node reference
* @return node reference of a rule set
*/
@Auditable(parameters = {"folderNodeRef"})
@Experimental
NodeRef getRuleSetNode(final NodeRef folderNodeRef);
/**
* Check if rule set's associated parent matches folder node.
*
* @param ruleSetNodeRef - node reference of a rule set
* @param folderNodeRef - node reference of a folder
* @return true if rule set is associated with folder
*/
@Auditable(parameters = {"nodeRef"})
@Auditable(parameters = {"ruleSetNodeRef", "folderNodeRef"})
@Experimental
boolean isRuleSetAssociatedWithFolder(NodeRef ruleSetNodeRef, NodeRef folderNodeRef);
/**
* Check if rule's associated parent matches rule set node.
*
* @param ruleNodeRef - node reference of a rule
* @param ruleSetNodeRef - node reference of a rule set
* @return true if rule is associated with rule set
*/
@Auditable(parameters = {"ruleNodeRef", "ruleSetNodeRef"})
@Experimental
boolean isRuleAssociatedWithRuleSet(final NodeRef ruleNodeRef, final NodeRef ruleSetNodeRef);
/**
* Check if others folders are linked to rule set.
*
* @param ruleSetNodeRef - node reference of a rule set
* @return true if others folders are linked to rule set
*/
@Auditable(parameters = {"ruleSetNodeRef"})
@Experimental
boolean isRuleSetShared(final NodeRef ruleSetNodeRef);
}

View File

@@ -73,6 +73,7 @@ import org.junit.runners.Suite;
org.alfresco.repo.rendition.RenditionNodeManagerTest.class,
org.alfresco.repo.rendition.RenditionServiceImplTest.class,
org.alfresco.repo.replication.ReplicationServiceImplTest.class,
org.alfresco.repo.rule.RuleServiceImplUnitTest.class,
org.alfresco.repo.service.StoreRedirectorProxyFactoryTest.class,
org.alfresco.repo.site.RoleComparatorImplTest.class,
org.alfresco.repo.tenant.MultiTAdminServiceImplTest.class,

View File

@@ -51,6 +51,10 @@ import org.junit.runners.Suite;
org.alfresco.repo.action.executer.ContentMetadataEmbedderTest.class,
org.alfresco.repo.action.executer.AsynchronousExtractorTest.class,
org.alfresco.repo.action.access.ActionAccessRestrictionAbstractBaseTest.class,
org.alfresco.repo.action.access.ActionAccessRestrictionTest.class,
org.alfresco.repo.action.access.AdminActionAccessRestrictionTest.class,
org.alfresco.repo.rule.RuleLinkTest.class,
org.alfresco.repo.rule.RuleServiceCoverageTest.class,
org.alfresco.repo.rule.RuleServiceImplTest.class,

View File

@@ -0,0 +1,127 @@
/*
* #%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.repo.action.access;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.service.cmr.action.Action;
import org.junit.Before;
import org.junit.Test;
import org.springframework.lang.NonNull;
import java.util.Properties;
import static org.junit.Assert.assertThrows;
public class ActionAccessRestrictionAbstractBaseTest {
private static final String GLOBAL_PROPERTIES_ACTION_EXPOSE_PREFIX = "org.alfresco.repo.action";
private static final String GLOBAL_PROPERTIES_ACTION_EXPOSE_SUFFIX = ".exposed";
private static final String CONTROLLED_CONTEXT = ActionAccessRestriction.V1_ACTION_CONTEXT;
private static final String NONCONTROLLED_CONTEXT = "random321";
private static final String MAIL_ACTION = "mail";
private ActionAccessRestrictionAbstractBase accessRestriction;
private Properties globalProperties;
@Before
public void setup() {
globalProperties = new Properties();
accessRestriction = new ActionAccessRestrictionAbstractBase() {
@Override
protected void innerVerifyAccessRestriction(Action action) {
throw new ActionAccessException("Executing verification");
}
};
accessRestriction.setConfigProperties(globalProperties);
}
@Test
public void skipVerificationForNullContext() {
Action action = getActionWithContext(MAIL_ACTION, null);
accessRestriction.verifyAccessRestriction(action);
}
@Test
public void skipVerificationForNonControlledContext() {
Action action = getActionWithContext(MAIL_ACTION, NONCONTROLLED_CONTEXT);
accessRestriction.verifyAccessRestriction(action);
}
@Test
public void callVerificationForControlledContext() {
Action action = getActionWithContext(MAIL_ACTION, CONTROLLED_CONTEXT);
assertThrows(ActionAccessException.class, () -> accessRestriction.verifyAccessRestriction(action));
}
@Test
public void skipVerificationForExposedActionConfig() {
setGlobalPropertiesActionExposed(MAIL_ACTION, null, true);
Action action = getActionWithContext(MAIL_ACTION, CONTROLLED_CONTEXT);
accessRestriction.verifyAccessRestriction(action);
}
@Test
public void skipVerificationForExposedActionContextConfig() {
setGlobalPropertiesActionExposed(MAIL_ACTION, CONTROLLED_CONTEXT, true);
Action action = getActionWithContext(MAIL_ACTION, CONTROLLED_CONTEXT);
accessRestriction.verifyAccessRestriction(action);
}
@Test
public void callVerificationForNonExposedActionConfig() {
setGlobalPropertiesActionExposed(MAIL_ACTION, null, false);
Action action = getActionWithContext(MAIL_ACTION, CONTROLLED_CONTEXT);
assertThrows(ActionAccessException.class, () -> accessRestriction.verifyAccessRestriction(action));
}
@Test
public void callVerificationForNonExposedActionContextConfig() {
setGlobalPropertiesActionExposed(MAIL_ACTION, CONTROLLED_CONTEXT, false);
Action action = getActionWithContext(MAIL_ACTION, CONTROLLED_CONTEXT);
assertThrows(ActionAccessException.class, () -> accessRestriction.verifyAccessRestriction(action));
}
private Action getActionWithContext(String actionName, String context) {
Action action = new ActionImpl(null, "12345", actionName);
ActionAccessRestriction.setActionContext(action, context);
return action;
}
private void setGlobalPropertiesActionExposed(@NonNull String action, String context, boolean isExposed) {
StringBuilder property = new StringBuilder(GLOBAL_PROPERTIES_ACTION_EXPOSE_PREFIX);
property.append("." + action);
if (context != null) {
property.append("." + context);
}
property.append(GLOBAL_PROPERTIES_ACTION_EXPOSE_SUFFIX);
globalProperties.setProperty(property.toString(), Boolean.toString(isExposed));
}
}

View File

@@ -0,0 +1,43 @@
/*
* #%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.repo.action.access;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.service.cmr.action.Action;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class ActionAccessRestrictionTest {
@Test
public void testSettingContext() {
Action mailAction = new ActionImpl(null, "12345", "mail");
ActionAccessRestriction.setActionContext(mailAction, ActionAccessRestriction.RULE_ACTION_CONTEXT);
assertEquals(ActionAccessRestriction.RULE_ACTION_CONTEXT, ActionAccessRestriction.getActionContext(mailAction));
}
}

View File

@@ -0,0 +1,89 @@
/*
* #%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.repo.action.access;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.util.BaseSpringTest;
import org.junit.Before;
import org.junit.Test;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.assertThrows;
public class AdminActionAccessRestrictionTest extends BaseSpringTest {
private static final String MAIL_ACTION = "mail";
private static final String CONTROLLED_CONTEXT = ActionAccessRestriction.V1_ACTION_CONTEXT;
private ActionAccessRestriction adminActionAccessRestriction;
@Before
public void setup() {
adminActionAccessRestriction = applicationContext.getBean("adminActionAccessRestriction", AdminActionAccessRestriction.class);
}
@Test
public void adminCanExecute() {
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
Action action = createMailAction();
adminActionAccessRestriction.verifyAccessRestriction(action);
}
@Test
public void systemCanExecute() {
AuthenticationUtil.setRunAsUserSystem();
Action action = createMailAction();
adminActionAccessRestriction.verifyAccessRestriction(action);
}
@Test
public void userCantExecute() {
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getGuestUserName());
Action action = createMailAction();
assertThrows(ActionAccessException.class, () -> adminActionAccessRestriction.verifyAccessRestriction(action));
}
private Action createMailAction() {
Map<String, Serializable> params = new HashMap<>();
params.put("from", "admin@alfresco.com");
params.put("to", "test@wp.pl");
params.put("subject", "test");
params.put("text", "test");
Action action = new ActionImpl(null, "123", MAIL_ACTION, params);
ActionAccessRestriction.setActionContext(action, CONTROLLED_CONTEXT);
return action;
}
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* 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
@@ -25,44 +25,39 @@
*/
package org.alfresco.repo.content.transform;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import java.io.IOException;
import java.util.Properties;
import java.util.StringJoiner;
import static org.alfresco.repo.content.transform.LocalTransformServiceRegistry.LOCAL_TRANSFORMER;
import static org.alfresco.repo.content.transform.LocalTransformServiceRegistry.URL;
import static org.junit.Assert.assertEquals;
import java.util.Properties;
import java.util.StringJoiner;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class LocalTransformServiceRegistryTest
{
@Spy
private Properties properties = new Properties();
private Properties properties;
@InjectMocks
LocalTransformServiceRegistry registry = new LocalTransformServiceRegistry();
@Rule
public MockitoRule initRule = MockitoJUnit.rule();
private LocalTransformServiceRegistry registry;
@Test
public void testGetTEngineUrlsSortedByName() throws IOException
public void testGetTEngineUrlsSortedByName()
{
properties.put(LOCAL_TRANSFORMER+"aa"+URL, "aa");
properties.put(LOCAL_TRANSFORMER+"engine1"+URL, "http_xxxx1");
properties.put(LOCAL_TRANSFORMER+"engine3"+URL, "http3");
properties.put(LOCAL_TRANSFORMER+"engine2"+URL, "http_xx2");
properties.put(LOCAL_TRANSFORMER+"bb"+URL, "bb");
properties.put(LOCAL_TRANSFORMER+"b"+URL, "b");
properties.put(LOCAL_TRANSFORMER + "aa" + URL, "aa");
properties.put(LOCAL_TRANSFORMER + "engine1" + URL, "http_xxxx1");
properties.put(LOCAL_TRANSFORMER + "engine3" + URL, "http3");
properties.put(LOCAL_TRANSFORMER + "engine2" + URL, "http_xx2");
properties.put(LOCAL_TRANSFORMER + "bb" + URL, "bb");
properties.put(LOCAL_TRANSFORMER + "b" + URL, "b");
StringJoiner orderEngineConfigRead = new StringJoiner(",");
registry.getTEngineUrlsSortedByName().forEach(name -> orderEngineConfigRead.add(name));
registry.getTEngineUrlsSortedByName().forEach(orderEngineConfigRead::add);
assertEquals("aa,b,bb,http_xxxx1,http_xx2,http3", orderEngineConfigRead.toString());
}
}

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