mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-10-29 15:21:53 +00:00
Compare commits
74 Commits
25.1.0.26
...
fix/t1_Ope
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d31842352d | ||
|
|
643510f1b4 | ||
|
|
5e2c8eac98 | ||
|
|
888d034b82 | ||
|
|
b16b116293 | ||
|
|
f4a6346471 | ||
|
|
70387a8a19 | ||
|
|
c4b9ee4284 | ||
|
|
1629daa28e | ||
|
|
c9f2b1f9c7 | ||
|
|
f00af42eee | ||
|
|
6849da5d48 | ||
|
|
d4816e71bd | ||
|
|
652e36bcac | ||
|
|
22b9bfd056 | ||
|
|
4743ee4d9a | ||
|
|
1d7ac4dfaf | ||
|
|
1a17f7a0cf | ||
|
|
7d98849187 | ||
|
|
cb92c78b3c | ||
|
|
733e232e42 | ||
|
|
6804d5e288 | ||
|
|
ef0a39871d | ||
|
|
6b929e45e7 | ||
|
|
7249bc91ff | ||
|
|
d20b00b9ae | ||
|
|
208e10c9b0 | ||
|
|
304c68444c | ||
|
|
2f0a502958 | ||
|
|
e6d3963ef6 | ||
|
|
5004d357b9 | ||
|
|
6c61e78b2a | ||
|
|
d5192922cf | ||
|
|
9e3cf355e1 | ||
|
|
d0f18ac1a5 | ||
|
|
bcf8a576e9 | ||
|
|
1a8ca698c7 | ||
|
|
cabb64f4cd | ||
|
|
3cd5cfbbe1 | ||
|
|
6d6e6d913e | ||
|
|
692da57e7f | ||
|
|
d4b0499c00 | ||
|
|
1b35495717 | ||
|
|
2b9b6b825c | ||
|
|
6244cb87b6 | ||
|
|
52c5f34e1a | ||
|
|
cd977453a4 | ||
|
|
1592f7fa1d | ||
|
|
ea36e77775 | ||
|
|
e5968a25f3 | ||
|
|
c02422077c | ||
|
|
021f7f98d4 | ||
|
|
9d9c7a8d73 | ||
|
|
96b5968ce4 | ||
|
|
7b3c24416c | ||
|
|
03412b7d5a | ||
|
|
ab34e52f4e | ||
|
|
fb45a3e3c2 | ||
|
|
d11a0deacc | ||
|
|
35c01f78c3 | ||
|
|
2ba65ac19d | ||
|
|
c7e79193b0 | ||
|
|
85648077e6 | ||
|
|
a5bf4c750b | ||
|
|
986c387412 | ||
|
|
7956830390 | ||
|
|
2421752f4d | ||
|
|
3be58cf5af | ||
|
|
c34212b1b3 | ||
|
|
da9c7c372c | ||
|
|
f204310364 | ||
|
|
7ac4c434e9 | ||
|
|
62a9d439b7 | ||
|
|
0253b399a2 |
44
.github/workflows/ci.yml
vendored
44
.github/workflows/ci.yml
vendored
@@ -337,7 +337,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version: ['10.2.18', '10.4', '10.5']
|
||||
version: ['10.5', '10.6']
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
|
||||
@@ -398,8 +398,8 @@ jobs:
|
||||
- name: "Clean Maven cache"
|
||||
run: bash ./scripts/ci/cleanup_cache.sh
|
||||
|
||||
repository_mariadb_10_6_tests:
|
||||
name: "Repository - MariaDB 10.6 tests"
|
||||
repository_mariadb_10_11_tests:
|
||||
name: "Repository - MariaDB 10.11 tests"
|
||||
runs-on: ubuntu-latest
|
||||
needs: [prepare]
|
||||
if: >
|
||||
@@ -416,10 +416,10 @@ jobs:
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
|
||||
- name: "Init"
|
||||
run: bash ./scripts/ci/init.sh
|
||||
- name: "Run MariaDB 10.6 database"
|
||||
- name: "Run MariaDB 10.11 database"
|
||||
run: docker compose -f ./scripts/ci/docker-compose/docker-compose-db.yaml --profile mariadb up -d
|
||||
env:
|
||||
MARIADB_VERSION: 10.6
|
||||
MARIADB_VERSION: 10.11
|
||||
- name: "Prepare Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.2.0
|
||||
@@ -540,8 +540,8 @@ jobs:
|
||||
- name: "Clean Maven cache"
|
||||
run: bash ./scripts/ci/cleanup_cache.sh
|
||||
|
||||
repository_postgresql_13_12_tests:
|
||||
name: "Repository - PostgreSQL 13.12 tests"
|
||||
repository_postgresql_14_15_tests:
|
||||
name: "Repository - PostgreSQL 14.15 tests"
|
||||
runs-on: ubuntu-latest
|
||||
needs: [prepare]
|
||||
if: >
|
||||
@@ -557,10 +557,10 @@ jobs:
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
|
||||
- name: "Init"
|
||||
run: bash ./scripts/ci/init.sh
|
||||
- name: "Run PostgreSQL 13.12 database"
|
||||
- name: "Run PostgreSQL 14.15 database"
|
||||
run: docker compose -f ./scripts/ci/docker-compose/docker-compose-db.yaml --profile postgres up -d
|
||||
env:
|
||||
POSTGRES_VERSION: 13.12
|
||||
POSTGRES_VERSION: 14.15
|
||||
- name: "Prepare Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.2.0
|
||||
@@ -610,16 +610,16 @@ jobs:
|
||||
- name: "Clean Maven cache"
|
||||
run: bash ./scripts/ci/cleanup_cache.sh
|
||||
|
||||
repository_postgresql_14_9_tests:
|
||||
name: "Repository - PostgreSQL 14.9 tests"
|
||||
repository_postgresql_15_10_tests:
|
||||
name: "Repository - PostgreSQL 15.10 tests"
|
||||
runs-on: ubuntu-latest
|
||||
needs: [prepare]
|
||||
if: >
|
||||
(((github.ref_name == 'master' || startsWith(github.ref_name, 'release/')) && github.event_name != 'pull_request' &&
|
||||
!contains(github.event.head_commit.message, '[skip db]')) ||
|
||||
contains(github.event.head_commit.message, '[db]')) &&
|
||||
!contains(github.event.head_commit.message, '[skip tests]') &&
|
||||
!contains(github.event.head_commit.message, '[force')
|
||||
!contains(github.event.head_commit.message, '[skip db]')) ||
|
||||
contains(github.event.head_commit.message, '[db]')) &&
|
||||
!contains(github.event.head_commit.message, '[skip tests]') &&
|
||||
!contains(github.event.head_commit.message, '[force')
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
|
||||
@@ -627,10 +627,10 @@ jobs:
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
|
||||
- name: "Init"
|
||||
run: bash ./scripts/ci/init.sh
|
||||
- name: "Run PostgreSQL 14.9 database"
|
||||
- name: "Run PostgreSQL 15.10 database"
|
||||
run: docker compose -f ./scripts/ci/docker-compose/docker-compose-db.yaml --profile postgres up -d
|
||||
env:
|
||||
POSTGRES_VERSION: 14.9
|
||||
POSTGRES_VERSION: 15.10
|
||||
- name: "Prepare Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.2.0
|
||||
@@ -680,8 +680,8 @@ jobs:
|
||||
- name: "Clean Maven cache"
|
||||
run: bash ./scripts/ci/cleanup_cache.sh
|
||||
|
||||
repository_postgresql_15_4_tests:
|
||||
name: "Repository - PostgreSQL 15.4 tests"
|
||||
repository_postgresql_16_6_tests:
|
||||
name: "Repository - PostgreSQL 16.6 tests"
|
||||
runs-on: ubuntu-latest
|
||||
needs: [prepare]
|
||||
if: >
|
||||
@@ -697,10 +697,10 @@ jobs:
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
|
||||
- name: "Init"
|
||||
run: bash ./scripts/ci/init.sh
|
||||
- name: "Run PostgreSQL 15.4 database"
|
||||
- name: "Run PostgreSQL 16.6 database"
|
||||
run: docker compose -f ./scripts/ci/docker-compose/docker-compose-db.yaml --profile postgres up -d
|
||||
env:
|
||||
POSTGRES_VERSION: 15.4
|
||||
POSTGRES_VERSION: 16.6
|
||||
- name: "Prepare Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.2.0
|
||||
@@ -1061,7 +1061,7 @@ jobs:
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
|
||||
- name: "Init"
|
||||
run: bash ./scripts/ci/init.sh
|
||||
- name: "Run Postgres 15.4 database"
|
||||
- name: "Run Postgres 16.6 database"
|
||||
run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile postgres up -d
|
||||
- name: "Prepare Report Portal"
|
||||
if: github.ref_name == 'master'
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
SOLR6_TAG=2.0.13
|
||||
POSTGRES_TAG=15.4
|
||||
SOLR6_TAG=2.0.14
|
||||
POSTGRES_TAG=16.6
|
||||
ACTIVEMQ_TAG=5.18.3-jre17-rockylinux8
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
@@ -427,7 +427,7 @@
|
||||
<configuration>
|
||||
<images>
|
||||
<image>
|
||||
<name>postgres:15.4</name>
|
||||
<name>postgres:16.6</name>
|
||||
<run>
|
||||
<ports>
|
||||
<port>${postgresql.tests.port}:${postgresql.port}</port>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -3315,7 +3315,7 @@ definitions:
|
||||
type: string
|
||||
pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))"
|
||||
description: |
|
||||
The name must not contain spaces or the following special characters: * " < > \ / ? : and |.
|
||||
The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |.
|
||||
The character . must not be used at the end of the name.
|
||||
aspectNames:
|
||||
type: array
|
||||
@@ -3346,7 +3346,7 @@ definitions:
|
||||
type: string
|
||||
pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))"
|
||||
description: |
|
||||
The name must not contain spaces or the following special characters: * " < > \ / ? : and |.
|
||||
The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |.
|
||||
The character . must not be used at the end of the name.
|
||||
nodeType:
|
||||
type: string
|
||||
@@ -3396,7 +3396,7 @@ definitions:
|
||||
type: string
|
||||
pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))"
|
||||
description: |
|
||||
The name must not contain spaces or the following special characters: * " < > \ / ? : and |.
|
||||
The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |.
|
||||
The character . must not be used at the end of the name.
|
||||
nodeType:
|
||||
type: string
|
||||
@@ -3429,7 +3429,7 @@ definitions:
|
||||
type: string
|
||||
pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))"
|
||||
description: |
|
||||
The name must not contain spaces or the following special characters: * " < > \ / ? : and |.
|
||||
The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |.
|
||||
The character . must not be used at the end of the name.
|
||||
nodeType:
|
||||
type: string
|
||||
@@ -3484,7 +3484,7 @@ definitions:
|
||||
type: string
|
||||
pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))"
|
||||
description: |
|
||||
The name must not contain spaces or the following special characters: * " < > \ / ? : and |.
|
||||
The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |.
|
||||
The character . must not be used at the end of the name.
|
||||
nodeType:
|
||||
type: string
|
||||
@@ -3549,7 +3549,7 @@ definitions:
|
||||
type: string
|
||||
pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))"
|
||||
description: |
|
||||
The name must not contain spaces or the following special characters: * " < > \ / ? : and |.
|
||||
The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |.
|
||||
The character . must not be used at the end of the name.
|
||||
properties:
|
||||
type: object
|
||||
@@ -3578,7 +3578,7 @@ definitions:
|
||||
type: string
|
||||
pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))"
|
||||
description: |
|
||||
The name must not contain spaces or the following special characters: * " < > \ / ? : and |.
|
||||
The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |.
|
||||
The character . must not be used at the end of the name.
|
||||
nodeType:
|
||||
type: string
|
||||
@@ -3637,7 +3637,7 @@ definitions:
|
||||
type: string
|
||||
pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))"
|
||||
description: |
|
||||
The name must not contain spaces or the following special characters: * " < > \ / ? : and |.
|
||||
The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |.
|
||||
The character . must not be used at the end of the name.
|
||||
nodeType:
|
||||
type: string
|
||||
@@ -3702,7 +3702,7 @@ definitions:
|
||||
type: string
|
||||
pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))"
|
||||
description: |
|
||||
The name must not contain spaces or the following special characters: * " < > \ / ? : and |.
|
||||
The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |.
|
||||
The character . must not be used at the end of the name.
|
||||
properties:
|
||||
type: object
|
||||
@@ -3729,7 +3729,7 @@ definitions:
|
||||
type: string
|
||||
pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))"
|
||||
description: |
|
||||
The name must not contain spaces or the following special characters: * " < > \ / ? : and |.
|
||||
The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |.
|
||||
The character . must not be used at the end of the name.
|
||||
nodeType:
|
||||
type: string
|
||||
@@ -3779,7 +3779,7 @@ definitions:
|
||||
type: string
|
||||
pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))"
|
||||
description: |
|
||||
The name must not contain spaces or the following special characters: * " < > \ / ? : and |.
|
||||
The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |.
|
||||
The character . must not be used at the end of the name.
|
||||
nodeType:
|
||||
type: string
|
||||
@@ -3881,7 +3881,7 @@ definitions:
|
||||
type: string
|
||||
pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))"
|
||||
description: |
|
||||
The name must not contain spaces or the following special characters: * " < > \ / ? : and |.
|
||||
The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |.
|
||||
The character . must not be used at the end of the name.
|
||||
nodeType:
|
||||
type: string
|
||||
@@ -3967,7 +3967,7 @@ definitions:
|
||||
type: string
|
||||
pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))"
|
||||
description: |
|
||||
The name must not contain spaces or the following special characters: * " < > \ / ? : and |.
|
||||
The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |.
|
||||
The character . must not be used at the end of the name.
|
||||
nodeType:
|
||||
type: string
|
||||
@@ -4027,7 +4027,7 @@ definitions:
|
||||
type: string
|
||||
pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))"
|
||||
description: |
|
||||
The name must not contain spaces or the following special characters: * " < > \ / ? : and |.
|
||||
The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |.
|
||||
The character . must not be used at the end of the name.
|
||||
nodeType:
|
||||
type: string
|
||||
@@ -4076,7 +4076,7 @@ definitions:
|
||||
type: string
|
||||
pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))"
|
||||
description: |
|
||||
The name must not contain spaces or the following special characters: * " < > \ / ? : and |.
|
||||
The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |.
|
||||
The character . must not be used at the end of the name.
|
||||
nodeType:
|
||||
type: string
|
||||
@@ -4141,7 +4141,7 @@ definitions:
|
||||
type: string
|
||||
pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))"
|
||||
description: |
|
||||
The name must not contain spaces or the following special characters: * " < > \ / ? : and |.
|
||||
The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |.
|
||||
The character . must not be used at the end of the name.
|
||||
properties:
|
||||
type: object
|
||||
@@ -4166,7 +4166,7 @@ definitions:
|
||||
type: string
|
||||
pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))"
|
||||
description: |
|
||||
The name must not contain spaces or the following special characters: * " < > \ / ? : and |.
|
||||
The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |.
|
||||
The character . must not be used at the end of the name.
|
||||
nodeType:
|
||||
type: string
|
||||
@@ -4223,7 +4223,7 @@ definitions:
|
||||
type: string
|
||||
pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))"
|
||||
description: |
|
||||
The name must not contain spaces or the following special characters: * " < > \ / ? : and |.
|
||||
The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |.
|
||||
The character . must not be used at the end of the name.
|
||||
nodeType:
|
||||
type: string
|
||||
@@ -4830,7 +4830,7 @@ definitions:
|
||||
type: string
|
||||
pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))"
|
||||
description: |
|
||||
The name must not contain spaces or the following special characters: * " < > \ / ? : and |.
|
||||
The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |.
|
||||
The character . must not be used at the end of the name.
|
||||
nodeType:
|
||||
type: string
|
||||
@@ -4852,7 +4852,7 @@ definitions:
|
||||
type: string
|
||||
pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))"
|
||||
description: |
|
||||
The name must not contain spaces or the following special characters: * " < > \ / ? : and |.
|
||||
The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |.
|
||||
The character . must not be used at the end of the name.
|
||||
nodeType:
|
||||
type: string
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
</project>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
SOLR6_TAG=2.0.13
|
||||
POSTGRES_TAG=15.4
|
||||
SOLR6_TAG=2.0.14
|
||||
POSTGRES_TAG=16.6
|
||||
ACTIVEMQ_TAG=5.18.3-jre17-rockylinux8
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<organization>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -437,6 +437,15 @@ public class People extends ModelRequest<People>
|
||||
restWrapper.processEmptyModel(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deauthorize a user
|
||||
*/
|
||||
public void deauthorizeUser()
|
||||
{
|
||||
RestRequest request = RestRequest.simpleRequest(HttpMethod.POST, "people/{personId}/deauthorize", this.person.getUsername(), restWrapper.getParameters());
|
||||
restWrapper.processEmptyModel(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update avatar image PUT call on 'people/{nodeId}/children
|
||||
*/
|
||||
@@ -514,4 +523,4 @@ public class People extends ModelRequest<People>
|
||||
return people.getFavorites();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.alfresco.rest.people.deauthorization.community;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import org.alfresco.rest.RestTest;
|
||||
import org.alfresco.utility.model.TestGroup;
|
||||
import org.alfresco.utility.model.UserModel;
|
||||
import org.alfresco.utility.testrail.ExecutionType;
|
||||
import org.alfresco.utility.testrail.annotation.TestRail;
|
||||
|
||||
/**
|
||||
* Verifies API behavior in community edition. Should be excluded in enterprise edition.
|
||||
*/
|
||||
@Test
|
||||
public class DeauthorizeSanityTests extends RestTest
|
||||
{
|
||||
private UserModel userModel;
|
||||
private UserModel adminUser;
|
||||
|
||||
@BeforeClass(alwaysRun = true)
|
||||
public void dataPreparation()
|
||||
{
|
||||
adminUser = dataUser.getAdminUser();
|
||||
userModel = dataUser.createRandomTestUser();
|
||||
}
|
||||
|
||||
@Test(groups = {TestGroup.REST_API, TestGroup.PEOPLE, TestGroup.SANITY})
|
||||
@TestRail(section = {TestGroup.REST_API, TestGroup.PEOPLE}, executionType = ExecutionType.SANITY,
|
||||
description = "Check if de-authorization is not implemented in Community Edition")
|
||||
public void deauthorizationIsNotImplementedInCommunityEdition()
|
||||
{
|
||||
restClient.authenticateUser(adminUser).withCoreAPI().usingUser(userModel).deauthorizeUser();
|
||||
restClient.assertStatusCodeIs(HttpStatus.NOT_IMPLEMENTED);
|
||||
|
||||
restClient.authenticateUser(userModel).withCoreAPI().usingUser(userModel).deauthorizeUser();
|
||||
restClient.assertStatusCodeIs(HttpStatus.NOT_IMPLEMENTED);
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
36
pom.xml
36
pom.xml
@@ -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>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Alfresco Community Repo Parent</name>
|
||||
|
||||
@@ -51,31 +51,31 @@
|
||||
<dependency.alfresco-server-root.version>7.0.1</dependency.alfresco-server-root.version>
|
||||
<dependency.activiti-engine.version>5.23.0</dependency.activiti-engine.version>
|
||||
<dependency.activiti.version>5.23.0</dependency.activiti.version>
|
||||
<dependency.alfresco-transform-core.version>5.1.5</dependency.alfresco-transform-core.version>
|
||||
<dependency.alfresco-transform-service.version>4.1.5</dependency.alfresco-transform-service.version>
|
||||
<dependency.alfresco-transform-core.version>5.1.6</dependency.alfresco-transform-core.version>
|
||||
<dependency.alfresco-transform-service.version>4.1.6</dependency.alfresco-transform-service.version>
|
||||
<dependency.alfresco-greenmail.version>7.1</dependency.alfresco-greenmail.version>
|
||||
<dependency.acs-event-model.version>1.0.2</dependency.acs-event-model.version>
|
||||
|
||||
<dependency.aspectj.version>1.9.22.1</dependency.aspectj.version>
|
||||
<dependency.spring.version>6.1.14</dependency.spring.version>
|
||||
<dependency.spring.version>6.2.1</dependency.spring.version>
|
||||
<dependency.spring-security.version>6.3.4</dependency.spring-security.version>
|
||||
<dependency.antlr.version>3.5.3</dependency.antlr.version>
|
||||
<dependency.jackson.version>2.17.2</dependency.jackson.version>
|
||||
<dependency.cxf.version>4.0.5</dependency.cxf.version>
|
||||
<dependency.cxf.version>4.1.0</dependency.cxf.version>
|
||||
<dependency.opencmis.version>1.0.0-jakarta-1</dependency.opencmis.version>
|
||||
<dependency.webscripts.version>9.4</dependency.webscripts.version>
|
||||
<dependency.webscripts.version>10.0</dependency.webscripts.version>
|
||||
<dependency.bouncycastle.version>1.79</dependency.bouncycastle.version>
|
||||
<dependency.mockito-core.version>5.14.1</dependency.mockito-core.version>
|
||||
<dependency.assertj.version>3.26.3</dependency.assertj.version>
|
||||
<dependency.assertj.version>3.27.3</dependency.assertj.version>
|
||||
<dependency.org-json.version>20240303</dependency.org-json.version>
|
||||
<dependency.commons-dbcp.version>2.12.0</dependency.commons-dbcp.version>
|
||||
<dependency.commons-io.version>2.18.0</dependency.commons-io.version>
|
||||
<dependency.gson.version>2.11.0</dependency.gson.version>
|
||||
<dependency.gson.version>2.12.1</dependency.gson.version>
|
||||
<dependency.guava.version>33.3.1-jre</dependency.guava.version>
|
||||
<dependency.httpclient.version>4.5.14</dependency.httpclient.version>
|
||||
<dependency.httpcore.version>4.4.16</dependency.httpcore.version>
|
||||
<dependency.httpcomponents-httpclient5.version>5.4.1</dependency.httpcomponents-httpclient5.version>
|
||||
<dependency.httpcomponents-httpcore5.version>5.3</dependency.httpcomponents-httpcore5.version>
|
||||
<dependency.httpcomponents-httpcore5.version>5.3.3</dependency.httpcomponents-httpcore5.version>
|
||||
<dependency.commons-httpclient.version>3.1-HTTPCLIENT-1265</dependency.commons-httpclient.version>
|
||||
<dependency.xercesImpl.version>2.12.2</dependency.xercesImpl.version>
|
||||
<dependency.slf4j.version>2.0.16</dependency.slf4j.version>
|
||||
@@ -86,12 +86,12 @@
|
||||
<dependency.poi.version>5.3.0</dependency.poi.version>
|
||||
<dependency.jboss.logging.version>3.5.0.Final</dependency.jboss.logging.version>
|
||||
<dependency.camel.version>4.6.0</dependency.camel.version> <!-- when bumping this version, please keep track/sync with included netty.io dependencies -->
|
||||
<dependency.netty.version>4.1.113.Final</dependency.netty.version> <!-- must be in sync with camels transitive dependencies, e.g.: netty-common -->
|
||||
<dependency.netty.version>4.1.117.Final</dependency.netty.version> <!-- must be in sync with camels transitive dependencies, e.g.: netty-common -->
|
||||
<dependency.activemq.version>5.18.6</dependency.activemq.version>
|
||||
<dependency.apache-compress.version>1.27.1</dependency.apache-compress.version>
|
||||
<dependency.awaitility.version>4.2.2</dependency.awaitility.version>
|
||||
<dependency.swagger-ui.version>4.1.3</dependency.swagger-ui.version>
|
||||
<dependency.swagger-parser.version>1.0.72</dependency.swagger-parser.version>
|
||||
<dependency.swagger-parser.version>1.0.73</dependency.swagger-parser.version>
|
||||
<dependency.maven-filtering.version>3.1.1</dependency.maven-filtering.version>
|
||||
<dependency.maven-artifact.version>3.8.6</dependency.maven-artifact.version>
|
||||
<dependency.jdom2.version>2.0.6.1</dependency.jdom2.version>
|
||||
@@ -115,15 +115,15 @@
|
||||
<dependency.json-smart.version>2.5.1</dependency.json-smart.version>
|
||||
<alfresco.googledrive.version>4.1.0</alfresco.googledrive.version>
|
||||
<alfresco.aos-module.version>3.2.0</alfresco.aos-module.version>
|
||||
<alfresco.api-explorer.version>23.4.0</alfresco.api-explorer.version> <!-- Also in alfresco-enterprise-share -->
|
||||
<alfresco.api-explorer.version>25.1.0-A1</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.4.0</license-maven-plugin.version>
|
||||
<spotless-plugin.version>2.43.0</spotless-plugin.version>
|
||||
<spotless-plugin.version>2.44.2</spotless-plugin.version>
|
||||
<!-- Do not match any files by default, but this can be overridden from the command line. -->
|
||||
<spotless-include-list>NO_AUTOMATED_FORMATTING</spotless-include-list>
|
||||
|
||||
<dependency.postgresql.version>42.7.4</dependency.postgresql.version>
|
||||
<dependency.postgresql.version>42.7.5</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>
|
||||
@@ -155,7 +155,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>25.1.0.26</tag>
|
||||
<tag>HEAD</tag>
|
||||
</scm>
|
||||
|
||||
<distributionManagement>
|
||||
@@ -415,7 +415,7 @@
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.17.1</version>
|
||||
<version>1.18.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
@@ -704,7 +704,7 @@
|
||||
<dependency>
|
||||
<groupId>com.networknt</groupId>
|
||||
<artifactId>json-schema-validator</artifactId>
|
||||
<version>1.5.4</version>
|
||||
<version>1.5.5</version>
|
||||
</dependency>
|
||||
<!-- upgrade dependency from TIKA -->
|
||||
<dependency>
|
||||
@@ -794,7 +794,7 @@
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>2.13.0</version>
|
||||
<version>2.13.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- provided dependencies -->
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -1,234 +1,248 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2023 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.people;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.rest.api.People;
|
||||
import org.alfresco.rest.api.model.Client;
|
||||
import org.alfresco.rest.api.model.PasswordReset;
|
||||
import org.alfresco.rest.api.model.Person;
|
||||
import org.alfresco.rest.framework.BinaryProperties;
|
||||
import org.alfresco.rest.framework.Operation;
|
||||
import org.alfresco.rest.framework.WebApiDescription;
|
||||
import org.alfresco.rest.framework.WebApiNoAuth;
|
||||
import org.alfresco.rest.framework.WebApiParam;
|
||||
import org.alfresco.rest.framework.core.ResourceParameter;
|
||||
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
|
||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||
import org.alfresco.rest.framework.resource.EntityResource;
|
||||
import org.alfresco.rest.framework.resource.actions.interfaces.BinaryResourceAction;
|
||||
import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction;
|
||||
import org.alfresco.rest.framework.resource.content.BasicContentInfo;
|
||||
import org.alfresco.rest.framework.resource.content.BinaryResource;
|
||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||
import org.alfresco.rest.framework.webscripts.WithResponse;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
/**
|
||||
* An implementation of an Entity Resource for a Person
|
||||
*
|
||||
* @author sglover
|
||||
* @author Gethin James
|
||||
*/
|
||||
@EntityResource(name="people", title = "People")
|
||||
public class PeopleEntityResource implements EntityResourceAction.ReadById<Person>, EntityResourceAction.Create<Person>,
|
||||
EntityResourceAction.Update<Person>,EntityResourceAction.Read<Person>,
|
||||
|
||||
BinaryResourceAction.Read, BinaryResourceAction.Update<Person>, BinaryResourceAction.Delete, InitializingBean
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(PeopleEntityResource.class);
|
||||
|
||||
private People people;
|
||||
|
||||
public void setPeople(People people)
|
||||
{
|
||||
this.people = people;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet()
|
||||
{
|
||||
PropertyCheck.mandatory(this, "people", people);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a person by userName.
|
||||
*
|
||||
* @see org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction.ReadById#readById(String, org.alfresco.rest.framework.resource.parameters.Parameters)
|
||||
*/
|
||||
@Override
|
||||
@WebApiDescription(title = "Get Person Information", description = "Get information for the person with id 'personId'")
|
||||
@WebApiParam(name = "personId", title = "The person's username")
|
||||
public Person readById(String personId, Parameters parameters)
|
||||
{
|
||||
Person person = people.getPerson(personId);
|
||||
return person;
|
||||
}
|
||||
|
||||
@Override
|
||||
@WebApiDescription(title="Create person", description="Create a person")
|
||||
@WebApiParam(name="persons", title="A single person", description="A single person, multiple people are not supported.",
|
||||
kind= ResourceParameter.KIND.HTTP_BODY_OBJECT, allowMultiple=false, required = true)
|
||||
public List<Person> create(List<Person> persons, Parameters parameters)
|
||||
{
|
||||
Person p = persons.get(0);
|
||||
|
||||
validateDerivedFieldsExistence(p);
|
||||
|
||||
List<Person> result = new ArrayList<>(1);
|
||||
result.add(people.create(p));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@WebApiDescription(title="Update person", description="Update the given person's details")
|
||||
public Person update(String personId, Person person, Parameters parameters)
|
||||
{
|
||||
if (person.wasSet(ContentModel.PROP_USERNAME))
|
||||
{
|
||||
// REPO-1537
|
||||
throw new InvalidArgumentException("Unsupported field: id");
|
||||
}
|
||||
|
||||
validateDerivedFieldsExistence(person);
|
||||
|
||||
return people.update(personId, person);
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicitly test for the presence of system-maintained (derived) fields that are settable on Person (see also REPO-110).
|
||||
*
|
||||
* @param person
|
||||
*/
|
||||
private void validateDerivedFieldsExistence(Person person)
|
||||
{
|
||||
if (person.wasSet(ContentModel.PROP_USER_STATUS_TIME))
|
||||
{
|
||||
throw new InvalidArgumentException("Unsupported field: statusUpdatedAt");
|
||||
}
|
||||
|
||||
if (person.wasSet(Person.PROP_PERSON_AVATAR_ID))
|
||||
{
|
||||
throw new InvalidArgumentException("Unsupported field: avatarId");
|
||||
}
|
||||
|
||||
if (person.wasSet(ContentModel.PROP_SIZE_QUOTA))
|
||||
{
|
||||
throw new InvalidArgumentException("Unsupported field: quota");
|
||||
}
|
||||
|
||||
if (person.wasSet(ContentModel.PROP_SIZE_CURRENT))
|
||||
{
|
||||
throw new InvalidArgumentException("Unsupported field: quotaUsed");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@WebApiDescription(title = "Get List of People", description = "Get List of People")
|
||||
public CollectionWithPagingInfo<Person> readAll(Parameters params)
|
||||
{
|
||||
return people.getPeople(params);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Operation("request-password-reset")
|
||||
@WebApiDescription(title = "Request Password Reset", description = "Request password reset",
|
||||
successStatus = HttpServletResponse.SC_ACCEPTED)
|
||||
@WebApiNoAuth
|
||||
public void requestPasswordReset(String personId, Client client, Parameters parameters, WithResponse withResponse)
|
||||
{
|
||||
people.requestPasswordReset(personId, client.getClient());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Operation("reset-password")
|
||||
@WebApiDescription(title = "Reset Password", description = "Performs password reset", successStatus = HttpServletResponse.SC_ACCEPTED)
|
||||
@WebApiNoAuth
|
||||
public void resetPassword(String personId, PasswordReset passwordReset, Parameters parameters, WithResponse withResponse)
|
||||
{
|
||||
people.resetPassword(personId, passwordReset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Download avatar image content
|
||||
*
|
||||
* @param personId
|
||||
* @param parameters {@link Parameters}
|
||||
* @return
|
||||
* @throws EntityNotFoundException
|
||||
*/
|
||||
@Override
|
||||
@WebApiDescription(title = "Download avatar", description = "Download avatar")
|
||||
@BinaryProperties({"avatar"})
|
||||
public BinaryResource readProperty(String personId, Parameters parameters) throws EntityNotFoundException
|
||||
{
|
||||
return people.downloadAvatarContent(personId, parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload avatar image content
|
||||
*
|
||||
* @param personId
|
||||
* @param contentInfo Basic information about the content stream
|
||||
* @param stream An inputstream
|
||||
* @param parameters
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@WebApiDescription(title = "Upload avatar", description = "Upload avatar")
|
||||
@BinaryProperties({"avatar"})
|
||||
public Person updateProperty(String personId, BasicContentInfo contentInfo, InputStream stream, Parameters parameters)
|
||||
{
|
||||
return people.uploadAvatarContent(personId, contentInfo, stream, parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete avatar image content
|
||||
*
|
||||
* @param personId
|
||||
* @param parameters
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@WebApiDescription(title = "Delete avatar image", description = "Delete avatar image")
|
||||
@BinaryProperties({ "avatar" })
|
||||
public void deleteProperty(String personId, Parameters parameters)
|
||||
{
|
||||
people.deleteAvatarContent(personId);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2025 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.people;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.rest.api.People;
|
||||
import org.alfresco.rest.api.model.Client;
|
||||
import org.alfresco.rest.api.model.PasswordReset;
|
||||
import org.alfresco.rest.api.model.Person;
|
||||
import org.alfresco.rest.framework.BinaryProperties;
|
||||
import org.alfresco.rest.framework.Operation;
|
||||
import org.alfresco.rest.framework.WebApiDescription;
|
||||
import org.alfresco.rest.framework.WebApiNoAuth;
|
||||
import org.alfresco.rest.framework.WebApiParam;
|
||||
import org.alfresco.rest.framework.core.ResourceParameter;
|
||||
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
|
||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||
import org.alfresco.rest.framework.resource.EntityResource;
|
||||
import org.alfresco.rest.framework.resource.actions.interfaces.BinaryResourceAction;
|
||||
import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction;
|
||||
import org.alfresco.rest.framework.resource.content.BasicContentInfo;
|
||||
import org.alfresco.rest.framework.resource.content.BinaryResource;
|
||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||
import org.alfresco.rest.framework.webscripts.WithResponse;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
|
||||
/**
|
||||
* An implementation of an Entity Resource for a Person
|
||||
*
|
||||
* @author sglover
|
||||
* @author Gethin James
|
||||
*/
|
||||
@EntityResource(name = "people", title = "People")
|
||||
public class PeopleEntityResource implements EntityResourceAction.ReadById<Person>, EntityResourceAction.Create<Person>,
|
||||
EntityResourceAction.Update<Person>, EntityResourceAction.Read<Person>,
|
||||
|
||||
BinaryResourceAction.Read, BinaryResourceAction.Update<Person>, BinaryResourceAction.Delete, InitializingBean
|
||||
{
|
||||
private People people;
|
||||
|
||||
public void setPeople(People people)
|
||||
{
|
||||
this.people = people;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet()
|
||||
{
|
||||
PropertyCheck.mandatory(this, "people", people);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a person by userName.
|
||||
*
|
||||
* @see org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction.ReadById#readById(String, org.alfresco.rest.framework.resource.parameters.Parameters)
|
||||
*/
|
||||
@Override
|
||||
@WebApiDescription(title = "Get Person Information", description = "Get information for the person with id 'personId'")
|
||||
@WebApiParam(name = "personId", title = "The person's username")
|
||||
public Person readById(String personId, Parameters parameters)
|
||||
{
|
||||
Person person = people.getPerson(personId);
|
||||
return person;
|
||||
}
|
||||
|
||||
@Override
|
||||
@WebApiDescription(title = "Create person", description = "Create a person")
|
||||
@WebApiParam(name = "persons", title = "A single person", description = "A single person, multiple people are not supported.",
|
||||
kind = ResourceParameter.KIND.HTTP_BODY_OBJECT, allowMultiple = false, required = true)
|
||||
public List<Person> create(List<Person> persons, Parameters parameters)
|
||||
{
|
||||
Person p = persons.get(0);
|
||||
|
||||
validateDerivedFieldsExistence(p);
|
||||
|
||||
List<Person> result = new ArrayList<>(1);
|
||||
result.add(people.create(p));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@WebApiDescription(title = "Update person", description = "Update the given person's details")
|
||||
public Person update(String personId, Person person, Parameters parameters)
|
||||
{
|
||||
if (person.wasSet(ContentModel.PROP_USERNAME))
|
||||
{
|
||||
// REPO-1537
|
||||
throw new InvalidArgumentException("Unsupported field: id");
|
||||
}
|
||||
|
||||
validateDerivedFieldsExistence(person);
|
||||
|
||||
return people.update(personId, person);
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicitly test for the presence of system-maintained (derived) fields that are settable on Person (see also REPO-110).
|
||||
*
|
||||
* @param person
|
||||
*/
|
||||
private void validateDerivedFieldsExistence(Person person)
|
||||
{
|
||||
if (person.wasSet(ContentModel.PROP_USER_STATUS_TIME))
|
||||
{
|
||||
throw new InvalidArgumentException("Unsupported field: statusUpdatedAt");
|
||||
}
|
||||
|
||||
if (person.wasSet(Person.PROP_PERSON_AVATAR_ID))
|
||||
{
|
||||
throw new InvalidArgumentException("Unsupported field: avatarId");
|
||||
}
|
||||
|
||||
if (person.wasSet(ContentModel.PROP_SIZE_QUOTA))
|
||||
{
|
||||
throw new InvalidArgumentException("Unsupported field: quota");
|
||||
}
|
||||
|
||||
if (person.wasSet(ContentModel.PROP_SIZE_CURRENT))
|
||||
{
|
||||
throw new InvalidArgumentException("Unsupported field: quotaUsed");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@WebApiDescription(title = "Get List of People", description = "Get List of People")
|
||||
public CollectionWithPagingInfo<Person> readAll(Parameters params)
|
||||
{
|
||||
return people.getPeople(params);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Operation("request-password-reset")
|
||||
@WebApiDescription(title = "Request Password Reset", description = "Request password reset",
|
||||
successStatus = HttpServletResponse.SC_ACCEPTED)
|
||||
@WebApiNoAuth
|
||||
public void requestPasswordReset(String personId, Client client, Parameters parameters, WithResponse withResponse)
|
||||
{
|
||||
people.requestPasswordReset(personId, client.getClient());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Operation("reset-password")
|
||||
@WebApiDescription(title = "Reset Password", description = "Performs password reset", successStatus = HttpServletResponse.SC_ACCEPTED)
|
||||
@WebApiNoAuth
|
||||
public void resetPassword(String personId, PasswordReset passwordReset, Parameters parameters, WithResponse withResponse)
|
||||
{
|
||||
people.resetPassword(personId, passwordReset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Download avatar image content
|
||||
*
|
||||
* @param personId
|
||||
* @param parameters
|
||||
* {@link Parameters}
|
||||
* @return
|
||||
* @throws EntityNotFoundException
|
||||
*/
|
||||
@Override
|
||||
@WebApiDescription(title = "Download avatar", description = "Download avatar")
|
||||
@BinaryProperties({"avatar"})
|
||||
public BinaryResource readProperty(String personId, Parameters parameters) throws EntityNotFoundException
|
||||
{
|
||||
return people.downloadAvatarContent(personId, parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload avatar image content
|
||||
*
|
||||
* @param personId
|
||||
* @param contentInfo
|
||||
* Basic information about the content stream
|
||||
* @param stream
|
||||
* An inputstream
|
||||
* @param parameters
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@WebApiDescription(title = "Upload avatar", description = "Upload avatar")
|
||||
@BinaryProperties({"avatar"})
|
||||
public Person updateProperty(String personId, BasicContentInfo contentInfo, InputStream stream, Parameters parameters)
|
||||
{
|
||||
return people.uploadAvatarContent(personId, contentInfo, stream, parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete avatar image content
|
||||
*
|
||||
* @param personId
|
||||
* @param parameters
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@WebApiDescription(title = "Delete avatar image", description = "Delete avatar image")
|
||||
@BinaryProperties({"avatar"})
|
||||
public void deleteProperty(String personId, Parameters parameters)
|
||||
{
|
||||
people.deleteAvatarContent(personId);
|
||||
}
|
||||
|
||||
/**
|
||||
* De-authorize user
|
||||
*
|
||||
* Not currently supported in community edition.
|
||||
*
|
||||
* @param personId
|
||||
* @param body
|
||||
* @param parameters
|
||||
* @param withResponse
|
||||
*/
|
||||
@Operation("deauthorize")
|
||||
@WebApiDescription(title = "De-authorize user", description = "Performs user de-authorization", successStatus = HttpServletResponse.SC_NOT_IMPLEMENTED)
|
||||
public void deauthorizeUser(String personId, Void body, Parameters parameters, WithResponse withResponse)
|
||||
{
|
||||
// functionality is not implemented in community edition
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1116,7 +1116,7 @@
|
||||
<property name="siteMembershipRequests" ref="SiteMembershipRequests" />
|
||||
</bean>
|
||||
|
||||
<bean class="org.alfresco.rest.api.people.PeopleEntityResource">
|
||||
<bean id="peopleEntityResource" class="org.alfresco.rest.api.people.PeopleEntityResource">
|
||||
<property name="people" ref="People" />
|
||||
</bean>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>25.1.0.26</version>
|
||||
<version>25.1.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2025 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -42,6 +42,9 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.event.v1.model.ContentInfo;
|
||||
@@ -50,6 +53,7 @@ import org.alfresco.repo.event.v1.model.UserInfo;
|
||||
import org.alfresco.repo.event2.filter.EventFilterRegistry;
|
||||
import org.alfresco.repo.event2.filter.NodeAspectFilter;
|
||||
import org.alfresco.repo.event2.filter.NodePropertyFilter;
|
||||
import org.alfresco.repo.event2.mapper.PropertyMapper;
|
||||
import org.alfresco.repo.node.MLPropertyInterceptor;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
@@ -68,9 +72,6 @@ import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.PathUtil;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
/**
|
||||
* Helper for {@link NodeResource} objects.
|
||||
@@ -81,14 +82,15 @@ public class NodeResourceHelper implements InitializingBean
|
||||
{
|
||||
private static final Log LOGGER = LogFactory.getLog(NodeResourceHelper.class);
|
||||
|
||||
protected NodeService nodeService;
|
||||
protected DictionaryService dictionaryService;
|
||||
protected PersonService personService;
|
||||
protected NodeService nodeService;
|
||||
protected DictionaryService dictionaryService;
|
||||
protected PersonService personService;
|
||||
protected EventFilterRegistry eventFilterRegistry;
|
||||
protected NamespaceService namespaceService;
|
||||
protected PermissionService permissionService;
|
||||
protected NamespaceService namespaceService;
|
||||
protected PermissionService permissionService;
|
||||
protected PropertyMapper propertyMapper;
|
||||
|
||||
private NodeAspectFilter nodeAspectFilter;
|
||||
private NodeAspectFilter nodeAspectFilter;
|
||||
private NodePropertyFilter nodePropertyFilter;
|
||||
|
||||
@Override
|
||||
@@ -100,6 +102,7 @@ public class NodeResourceHelper implements InitializingBean
|
||||
PropertyCheck.mandatory(this, "eventFilterRegistry", eventFilterRegistry);
|
||||
PropertyCheck.mandatory(this, "namespaceService", namespaceService);
|
||||
PropertyCheck.mandatory(this, "permissionService", permissionService);
|
||||
PropertyCheck.mandatory(this, "propertyMapper", propertyMapper);
|
||||
|
||||
this.nodeAspectFilter = eventFilterRegistry.getNodeAspectFilter();
|
||||
this.nodePropertyFilter = eventFilterRegistry.getNodePropertyFilter();
|
||||
@@ -124,7 +127,7 @@ public class NodeResourceHelper implements InitializingBean
|
||||
{
|
||||
this.permissionService = permissionService;
|
||||
}
|
||||
|
||||
|
||||
// To make IntelliJ stop complaining about unused method!
|
||||
@SuppressWarnings("unused")
|
||||
public void setEventFilterRegistry(EventFilterRegistry eventFilterRegistry)
|
||||
@@ -137,6 +140,11 @@ public class NodeResourceHelper implements InitializingBean
|
||||
this.namespaceService = namespaceService;
|
||||
}
|
||||
|
||||
public void setPropertyMapper(PropertyMapper propertyMapper)
|
||||
{
|
||||
this.propertyMapper = propertyMapper;
|
||||
}
|
||||
|
||||
public NodeResource.Builder createNodeResourceBuilder(NodeRef nodeRef)
|
||||
{
|
||||
final QName type = nodeService.getType(nodeRef);
|
||||
@@ -148,22 +156,22 @@ public class NodeResourceHelper implements InitializingBean
|
||||
Map<String, UserInfo> mapUserCache = new HashMap<>(2);
|
||||
|
||||
return NodeResource.builder()
|
||||
.setId(nodeRef.getId())
|
||||
.setName((String) properties.get(ContentModel.PROP_NAME))
|
||||
.setNodeType(getQNamePrefixString(type))
|
||||
.setIsFile(isSubClass(type, ContentModel.TYPE_CONTENT))
|
||||
.setIsFolder(isSubClass(type, ContentModel.TYPE_FOLDER))
|
||||
.setCreatedByUser(getUserInfo((String) properties.get(ContentModel.PROP_CREATOR), mapUserCache))
|
||||
.setCreatedAt(getZonedDateTime((Date)properties.get(ContentModel.PROP_CREATED)))
|
||||
.setModifiedByUser(getUserInfo((String) properties.get(ContentModel.PROP_MODIFIER), mapUserCache))
|
||||
.setModifiedAt(getZonedDateTime((Date)properties.get(ContentModel.PROP_MODIFIED)))
|
||||
.setContent(getContentInfo(properties))
|
||||
.setPrimaryAssocQName(getPrimaryAssocQName(nodeRef))
|
||||
.setPrimaryHierarchy(PathUtil.getNodeIdsInReverse(path, false))
|
||||
.setProperties(mapToNodeProperties(properties))
|
||||
.setLocalizedProperties(mapToNodeLocalizedProperties(properties))
|
||||
.setAspectNames(getMappedAspects(nodeRef))
|
||||
.setSecondaryParents(getSecondaryParents(nodeRef));
|
||||
.setId(nodeRef.getId())
|
||||
.setName((String) properties.get(ContentModel.PROP_NAME))
|
||||
.setNodeType(getQNamePrefixString(type))
|
||||
.setIsFile(isSubClass(type, ContentModel.TYPE_CONTENT))
|
||||
.setIsFolder(isSubClass(type, ContentModel.TYPE_FOLDER))
|
||||
.setCreatedByUser(getUserInfo((String) properties.get(ContentModel.PROP_CREATOR), mapUserCache))
|
||||
.setCreatedAt(getZonedDateTime((Date) properties.get(ContentModel.PROP_CREATED)))
|
||||
.setModifiedByUser(getUserInfo((String) properties.get(ContentModel.PROP_MODIFIER), mapUserCache))
|
||||
.setModifiedAt(getZonedDateTime((Date) properties.get(ContentModel.PROP_MODIFIED)))
|
||||
.setContent(getContentInfo(properties))
|
||||
.setPrimaryAssocQName(getPrimaryAssocQName(nodeRef))
|
||||
.setPrimaryHierarchy(PathUtil.getNodeIdsInReverse(path, false))
|
||||
.setProperties(mapToNodeProperties(properties))
|
||||
.setLocalizedProperties(mapToNodeLocalizedProperties(properties))
|
||||
.setAspectNames(getMappedAspects(nodeRef))
|
||||
.setSecondaryParents(getSecondaryParents(nodeRef));
|
||||
}
|
||||
|
||||
private boolean isSubClass(QName className, QName ofClassQName)
|
||||
@@ -171,17 +179,18 @@ public class NodeResourceHelper implements InitializingBean
|
||||
return dictionaryService.isSubClass(className, ofClassQName);
|
||||
}
|
||||
|
||||
private String getPrimaryAssocQName(NodeRef nodeRef)
|
||||
private String getPrimaryAssocQName(NodeRef nodeRef)
|
||||
{
|
||||
String result = null;
|
||||
try
|
||||
try
|
||||
{
|
||||
ChildAssociationRef primaryParent = nodeService.getPrimaryParent(nodeRef);
|
||||
if(primaryParent != null && primaryParent.getQName() != null)
|
||||
if (primaryParent != null && primaryParent.getQName() != null)
|
||||
{
|
||||
result = primaryParent.getQName().getPrefixedQName(namespaceService).getPrefixString();
|
||||
}
|
||||
} catch (NamespaceException namespaceException)
|
||||
}
|
||||
catch (NamespaceException namespaceException)
|
||||
{
|
||||
LOGGER.error("Cannot return a valid primary association QName: " + namespaceException.getMessage());
|
||||
}
|
||||
@@ -215,8 +224,8 @@ public class NodeResourceHelper implements InitializingBean
|
||||
{
|
||||
v = ((MLText) v).getDefaultValue();
|
||||
}
|
||||
|
||||
filteredProps.put(getQNamePrefixString(k), v);
|
||||
Serializable mappedValue = propertyMapper.map(k, v);
|
||||
filteredProps.put(getQNamePrefixString(k), mappedValue);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -232,7 +241,10 @@ public class NodeResourceHelper implements InitializingBean
|
||||
{
|
||||
final MLText mlTextValue = (MLText) v;
|
||||
final HashMap<String, String> localizedValues = new HashMap<>(mlTextValue.size());
|
||||
mlTextValue.forEach((locale, text) -> localizedValues.put(locale.toString(), text));
|
||||
mlTextValue.forEach((locale, text) -> {
|
||||
Serializable mappedValue = propertyMapper.map(k, text);
|
||||
localizedValues.put(locale.toString(), (String) mappedValue);
|
||||
});
|
||||
filteredProps.put(getQNamePrefixString(k), localizedValues);
|
||||
}
|
||||
});
|
||||
@@ -259,7 +271,7 @@ public class NodeResourceHelper implements InitializingBean
|
||||
{
|
||||
String sysUserName = AuthenticationUtil.getSystemUserName();
|
||||
if (userName.equals(sysUserName) || (AuthenticationUtil.isMtEnabled()
|
||||
&& userName.startsWith(sysUserName + "@")))
|
||||
&& userName.startsWith(sysUserName + "@")))
|
||||
{
|
||||
userInfo = new UserInfo(userName, userName, "");
|
||||
}
|
||||
@@ -306,11 +318,11 @@ public class NodeResourceHelper implements InitializingBean
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the QName in the format prefix:local, but in the exceptional case where there is no registered prefix
|
||||
* returns it in the form {uri}local.
|
||||
* Returns the QName in the format prefix:local, but in the exceptional case where there is no registered prefix returns it in the form {uri}local.
|
||||
*
|
||||
* @param k QName
|
||||
* @return a String representing the QName in the format prefix:local or {uri}local.
|
||||
* @param k
|
||||
* QName
|
||||
* @return a String representing the QName in the format prefix:local or {uri}local.
|
||||
*/
|
||||
public String getQNamePrefixString(QName k)
|
||||
{
|
||||
@@ -342,7 +354,7 @@ public class NodeResourceHelper implements InitializingBean
|
||||
|
||||
public QName getNodeType(NodeRef nodeRef)
|
||||
{
|
||||
return nodeService.getType(nodeRef);
|
||||
return nodeService.getType(nodeRef);
|
||||
}
|
||||
|
||||
public Serializable getProperty(NodeRef nodeRef, QName qName)
|
||||
@@ -352,13 +364,14 @@ public class NodeResourceHelper implements InitializingBean
|
||||
|
||||
public Map<QName, Serializable> getProperties(NodeRef nodeRef)
|
||||
{
|
||||
//We need to have full MLText properties here. This is why we are marking the current thread as MLAware
|
||||
// We need to have full MLText properties here. This is why we are marking the current thread as MLAware
|
||||
final boolean toRestore = MLPropertyInterceptor.isMLAware();
|
||||
MLPropertyInterceptor.setMLAware(true);
|
||||
try
|
||||
{
|
||||
return nodeService.getProperties(nodeRef);
|
||||
} finally
|
||||
}
|
||||
finally
|
||||
{
|
||||
MLPropertyInterceptor.setMLAware(toRestore);
|
||||
}
|
||||
@@ -377,7 +390,7 @@ public class NodeResourceHelper implements InitializingBean
|
||||
}
|
||||
|
||||
static Map<String, Map<String, String>> getLocalizedPropertiesBefore(Map<String, Map<String, String>> locPropsBefore,
|
||||
Map<String, Map<String, String>> locPropsAfter)
|
||||
Map<String, Map<String, String>> locPropsAfter)
|
||||
{
|
||||
final Map<String, Map<String, String>> result = new HashMap<>(locPropsBefore.size());
|
||||
|
||||
@@ -410,7 +423,7 @@ public class NodeResourceHelper implements InitializingBean
|
||||
{
|
||||
return mapToNodeAspects(nodeService.getAspects(nodeRef));
|
||||
}
|
||||
|
||||
|
||||
public List<String> getPrimaryHierarchy(NodeRef nodeRef, boolean showLeaf)
|
||||
{
|
||||
final Path path = nodeService.getPath(nodeRef);
|
||||
@@ -420,16 +433,17 @@ public class NodeResourceHelper implements InitializingBean
|
||||
/**
|
||||
* Gathers node's secondary parents.
|
||||
*
|
||||
* @param nodeRef - node reference
|
||||
* @param nodeRef
|
||||
* - node reference
|
||||
* @return a list of node's secondary parents.
|
||||
*/
|
||||
public List<String> getSecondaryParents(final NodeRef nodeRef)
|
||||
{
|
||||
return nodeService.getParentAssocs(nodeRef).stream()
|
||||
.filter(not(ChildAssociationRef::isPrimary))
|
||||
.map(ChildAssociationRef::getParentRef)
|
||||
.map(NodeRef::getId)
|
||||
.collect(Collectors.toList());
|
||||
.filter(not(ChildAssociationRef::isPrimary))
|
||||
.map(ChildAssociationRef::getParentRef)
|
||||
.map(NodeRef::getId)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public PermissionService getPermissionService()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2025 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,160 +26,50 @@
|
||||
package org.alfresco.repo.event2.filter;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.namespace.NamespaceException;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.repo.event2.shared.CSVStringToListParser;
|
||||
import org.alfresco.repo.event2.shared.QNameMatcher;
|
||||
import org.alfresco.repo.event2.shared.TypeDefExpander;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Abstract {@link EventFilter} implementation, containing common event filtering
|
||||
* functionality for the {@link QName} type.
|
||||
* Abstract {@link EventFilter} implementation, containing common event filtering functionality for the {@link QName} type.
|
||||
*
|
||||
* @author Jamal Kaabi-Mofrad
|
||||
*/
|
||||
public abstract class AbstractNodeEventFilter implements EventFilter<QName>
|
||||
{
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractNodeEventFilter.class);
|
||||
protected TypeDefExpander typeDefExpander;
|
||||
|
||||
private static final String MARKER_INCLUDE_SUBTYPES = "include_subtypes";
|
||||
private static final String WILDCARD = "*";
|
||||
|
||||
protected DictionaryService dictionaryService;
|
||||
protected NamespaceService namespaceService;
|
||||
|
||||
private Set<QName> excludedTypes;
|
||||
private Set<String> excludedNamespaceURI;
|
||||
|
||||
public AbstractNodeEventFilter()
|
||||
{
|
||||
this.excludedTypes = new HashSet<>();
|
||||
this.excludedNamespaceURI = new HashSet<>();
|
||||
}
|
||||
private QNameMatcher qNameMatcher;
|
||||
|
||||
public final void init()
|
||||
{
|
||||
preprocessExcludedTypes(getExcludedTypes());
|
||||
qNameMatcher = new QNameMatcher(getExcludedTypes());
|
||||
}
|
||||
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
public void setTypeDefExpander(TypeDefExpander typeDefExpander)
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
public void setNamespaceService(NamespaceService namespaceService)
|
||||
{
|
||||
this.namespaceService = namespaceService;
|
||||
this.typeDefExpander = typeDefExpander;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExcluded(QName qName)
|
||||
{
|
||||
if (qName != null)
|
||||
{
|
||||
return excludedTypes.contains(qName) || excludedNamespaceURI.contains(qName.getNamespaceURI());
|
||||
}
|
||||
return false;
|
||||
return qNameMatcher.isMatching(qName);
|
||||
}
|
||||
|
||||
protected abstract Set<QName> getExcludedTypes();
|
||||
|
||||
protected List<String> parseFilterList(String unparsedFilterList)
|
||||
{
|
||||
List<String> list = new LinkedList<>();
|
||||
|
||||
StringTokenizer st = new StringTokenizer(unparsedFilterList, ",");
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
String entry = st.nextToken().trim();
|
||||
if (!entry.isEmpty())
|
||||
{
|
||||
if (!entry.equals("none") && !entry.contains("${"))
|
||||
{
|
||||
list.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the user-defined list of types into valid QNames. It
|
||||
* validates them against the dictionary and also supports wildcards
|
||||
*/
|
||||
private void preprocessExcludedTypes(Set<QName> excluded)
|
||||
{
|
||||
excluded.forEach(qName -> {
|
||||
if (WILDCARD.equals(qName.getLocalName()))
|
||||
{
|
||||
//excludedPrefixes.add(getPrefix(qName));
|
||||
excludedNamespaceURI.add(qName.getNamespaceURI());
|
||||
}
|
||||
else
|
||||
{
|
||||
excludedTypes.add(qName);
|
||||
}
|
||||
});
|
||||
|
||||
if (LOGGER.isDebugEnabled())
|
||||
{
|
||||
LOGGER.debug("Excluded namespace URIs:" + excludedNamespaceURI);
|
||||
LOGGER.debug("Excluded types:" + excludedTypes);
|
||||
}
|
||||
}
|
||||
|
||||
private QName getQName(String type)
|
||||
{
|
||||
return QName.createQName(type, namespaceService);
|
||||
return CSVStringToListParser.parse(unparsedFilterList);
|
||||
}
|
||||
|
||||
protected Collection<QName> expandTypeDef(String typeDef)
|
||||
{
|
||||
if ((typeDef == null) || typeDef.isEmpty() || typeDef.equals("none") || typeDef.contains("${"))
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (typeDef.indexOf(' ') < 0)
|
||||
{
|
||||
return Collections.singleton(getQName(typeDef));
|
||||
}
|
||||
|
||||
String[] typeDefParts = typeDef.split(" ");
|
||||
if (typeDefParts.length != 2)
|
||||
{
|
||||
LOGGER.warn("Ignoring invalid blacklist type pattern: " + typeDef);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (typeDefParts[1].equals(MARKER_INCLUDE_SUBTYPES))
|
||||
{
|
||||
if (typeDefParts[0].indexOf('*') >= 0)
|
||||
{
|
||||
LOGGER.warn("Ignoring invalid blacklist type pattern: " + typeDef);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
QName baseType;
|
||||
try
|
||||
{
|
||||
baseType = getQName(typeDefParts[0]);
|
||||
}
|
||||
catch (NamespaceException ne)
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return dictionaryService.getSubTypes(baseType, true);
|
||||
}
|
||||
|
||||
LOGGER.warn("Ignoring invalid blacklist type pattern: " + typeDef);
|
||||
return Collections.emptyList();
|
||||
return typeDefExpander.expand(typeDef);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2025 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,6 +25,7 @@
|
||||
*/
|
||||
package org.alfresco.repo.event2.filter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -43,34 +44,37 @@ public class NodePropertyFilter extends AbstractNodeEventFilter
|
||||
// These properties are included as top-level info,
|
||||
// so exclude them from the properties object
|
||||
private static final Set<QName> EXCLUDED_TOP_LEVEL_PROPS = Set.of(ContentModel.PROP_NAME,
|
||||
ContentModel.PROP_MODIFIER,
|
||||
ContentModel.PROP_MODIFIED,
|
||||
ContentModel.PROP_CREATOR,
|
||||
ContentModel.PROP_CREATED,
|
||||
ContentModel.PROP_CONTENT);
|
||||
ContentModel.PROP_MODIFIER,
|
||||
ContentModel.PROP_MODIFIED,
|
||||
ContentModel.PROP_CREATOR,
|
||||
ContentModel.PROP_CREATED,
|
||||
ContentModel.PROP_CONTENT);
|
||||
// These properties should not be excluded from the properties object
|
||||
private static final Set<QName> ALLOWED_PROPERTIES = Set.of(ContentModel.PROP_CASCADE_TX,
|
||||
ContentModel.PROP_CASCADE_CRC);
|
||||
ContentModel.PROP_CASCADE_CRC);
|
||||
|
||||
private final List<String> nodePropertiesBlackList;
|
||||
private final List<String> nodePropertiesBlackList = new ArrayList<>();
|
||||
|
||||
public NodePropertyFilter()
|
||||
public NodePropertyFilter(String userConfiguredProperties)
|
||||
{
|
||||
this.nodePropertiesBlackList = parseFilterList(FILTERED_PROPERTIES);
|
||||
super();
|
||||
nodePropertiesBlackList.addAll(parseFilterList(FILTERED_PROPERTIES));
|
||||
nodePropertiesBlackList.addAll(parseFilterList(userConfiguredProperties));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<QName> getExcludedTypes()
|
||||
{
|
||||
Set<QName> result = new HashSet<>(EXCLUDED_TOP_LEVEL_PROPS);
|
||||
nodePropertiesBlackList.forEach(nodeProperty-> result.addAll(expandTypeDef(nodeProperty)));
|
||||
nodePropertiesBlackList.forEach(nodeProperty -> result.addAll(expandTypeDef(nodeProperty)));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExcluded(QName qName)
|
||||
{
|
||||
if(qName != null && ALLOWED_PROPERTIES.contains(qName)){
|
||||
if (qName != null && ALLOWED_PROPERTIES.contains(qName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return super.isExcluded(qName);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2025 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -31,6 +31,7 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
@@ -41,10 +42,13 @@ import org.alfresco.service.namespace.QName;
|
||||
public class NodeTypeFilter extends AbstractNodeEventFilter
|
||||
{
|
||||
private final List<String> nodeTypesBlackList;
|
||||
private final DictionaryService dictionaryService;
|
||||
|
||||
public NodeTypeFilter(String filteredNodeTypes)
|
||||
public NodeTypeFilter(String filteredNodeTypes, DictionaryService dictionaryService)
|
||||
{
|
||||
super();
|
||||
this.nodeTypesBlackList = parseFilterList(filteredNodeTypes);
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 2025 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.event2.mapper;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
public interface PropertyMapper
|
||||
{
|
||||
PropertyMapper NO_OP = (propertyQName, value) -> value;
|
||||
|
||||
Serializable map(QName propertyQName, Serializable value);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 2025 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.event2.mapper;
|
||||
|
||||
import org.alfresco.repo.event2.shared.CSVStringToListParser;
|
||||
import org.alfresco.repo.event2.shared.TypeDefExpander;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class PropertyMapperFactory
|
||||
{
|
||||
private final TypeDefExpander typeDefExpander;
|
||||
|
||||
public PropertyMapperFactory(TypeDefExpander typeDefExpander)
|
||||
{
|
||||
this.typeDefExpander = typeDefExpander;
|
||||
}
|
||||
|
||||
public PropertyMapper createPropertyMapper(String enabled, String userConfiguredSensitiveProperties, String userConfiguredReplacementText)
|
||||
{
|
||||
if ("false".equalsIgnoreCase(enabled))
|
||||
{
|
||||
return PropertyMapper.NO_OP;
|
||||
}
|
||||
Set<QName> sensitiveProperties = Optional.ofNullable(userConfiguredSensitiveProperties)
|
||||
.filter(Predicate.not(String::isEmpty))
|
||||
.map(CSVStringToListParser::parse)
|
||||
.map(typeDefExpander::expand)
|
||||
.orElse(Set.of());
|
||||
return new ReplaceSensitivePropertyWithTextMapper(sensitiveProperties, userConfiguredReplacementText);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 2025 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.event2.mapper;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.event2.shared.QNameMatcher;
|
||||
import org.alfresco.repo.transfer.TransferModel;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class ReplaceSensitivePropertyWithTextMapper implements PropertyMapper
|
||||
{
|
||||
private static final Set<QName> DEFAULT_SENSITIVE_PROPERTIES = Set.of(
|
||||
ContentModel.PROP_PASSWORD,
|
||||
ContentModel.PROP_SALT,
|
||||
ContentModel.PROP_PASSWORD_HASH,
|
||||
TransferModel.PROP_PASSWORD
|
||||
);
|
||||
private static final String DEFAULT_REPLACEMENT_TEXT = "SENSITIVE_DATA_REMOVED";
|
||||
|
||||
private final QNameMatcher qNameMatcher;
|
||||
private final String replacementText;
|
||||
|
||||
public ReplaceSensitivePropertyWithTextMapper(Set<QName> userConfiguredSensitiveProperties, String userConfiguredReplacementText)
|
||||
{
|
||||
Set<QName> sensitiveProperties = Optional.ofNullable(userConfiguredSensitiveProperties)
|
||||
.filter(Predicate.not(Collection::isEmpty))
|
||||
.orElse(DEFAULT_SENSITIVE_PROPERTIES);
|
||||
qNameMatcher = new QNameMatcher(sensitiveProperties);
|
||||
replacementText = Optional.ofNullable(userConfiguredReplacementText)
|
||||
.filter(Predicate.not(String::isEmpty))
|
||||
.filter(userInput -> !userInput.contains("${"))
|
||||
.orElse(DEFAULT_REPLACEMENT_TEXT);
|
||||
}
|
||||
@Override
|
||||
public Serializable map(QName propertyQName, Serializable value)
|
||||
{
|
||||
if (qNameMatcher.isMatching(propertyQName))
|
||||
{
|
||||
return replacementText;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 2025 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.event2.shared;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
public final class CSVStringToListParser
|
||||
{
|
||||
private CSVStringToListParser()
|
||||
{}
|
||||
|
||||
public static List<String> parse(String userInputCSV)
|
||||
{
|
||||
List<String> list = new LinkedList<>();
|
||||
|
||||
StringTokenizer st = new StringTokenizer(userInputCSV, ",");
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
String entry = st.nextToken().trim();
|
||||
if (!entry.isEmpty() && !entry.equals("none") && !entry.contains("${"))
|
||||
{
|
||||
list.add(entry);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 2025 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.event2.shared;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
public class QNameMatcher
|
||||
{
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(QNameMatcher.class);
|
||||
private static final String WILDCARD = "*";
|
||||
|
||||
private final Set<QName> matchingTypes;
|
||||
private final Set<String> matchingNamespaceURIs;
|
||||
|
||||
public QNameMatcher(Set<QName> qNamesToMatch)
|
||||
{
|
||||
matchingTypes = new HashSet<>();
|
||||
matchingNamespaceURIs = new HashSet<>();
|
||||
|
||||
qNamesToMatch.forEach(qName -> {
|
||||
if (WILDCARD.equals(qName.getLocalName()))
|
||||
{
|
||||
matchingNamespaceURIs.add(qName.getNamespaceURI());
|
||||
}
|
||||
else
|
||||
{
|
||||
matchingTypes.add(qName);
|
||||
}
|
||||
});
|
||||
|
||||
if (LOGGER.isDebugEnabled())
|
||||
{
|
||||
LOGGER.debug("Matching namespace URIs:" + matchingNamespaceURIs);
|
||||
LOGGER.debug("Matching types:" + matchingTypes);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isMatching(QName qName)
|
||||
{
|
||||
if (qName != null)
|
||||
{
|
||||
return matchingTypes.contains(qName) || matchingNamespaceURIs.contains(qName.getNamespaceURI());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 2025 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.event2.shared;
|
||||
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.namespace.NamespaceException;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class TypeDefExpander
|
||||
{
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TypeDefExpander.class);
|
||||
private static final String MARKER_INCLUDE_SUBTYPES = "include_subtypes";
|
||||
|
||||
private final DictionaryService dictionaryService;
|
||||
private final NamespaceService namespaceService;
|
||||
|
||||
public TypeDefExpander(DictionaryService dictionaryService, NamespaceService namespaceService)
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
this.namespaceService = namespaceService;
|
||||
}
|
||||
|
||||
public Set<QName> expand(Collection<String> types){
|
||||
Set<QName> result = new HashSet<>();
|
||||
types.forEach(type -> result.addAll(expand(type)));
|
||||
return result;
|
||||
}
|
||||
|
||||
public Collection<QName> expand(String typeDef)
|
||||
{
|
||||
if ((typeDef == null) || typeDef.isEmpty() || typeDef.equals("none") || typeDef.contains("${"))
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (typeDef.indexOf(' ') < 0)
|
||||
{
|
||||
return Collections.singleton(getQName(typeDef));
|
||||
}
|
||||
|
||||
String[] typeDefParts = typeDef.split(" ");
|
||||
if (typeDefParts.length != 2)
|
||||
{
|
||||
LOGGER.warn("Ignoring invalid type pattern: " + typeDef);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (typeDefParts[1].equals(MARKER_INCLUDE_SUBTYPES))
|
||||
{
|
||||
if (typeDefParts[0].indexOf('*') >= 0)
|
||||
{
|
||||
LOGGER.warn("Ignoring invalid type pattern: " + typeDef);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
QName baseType;
|
||||
try
|
||||
{
|
||||
baseType = getQName(typeDefParts[0]);
|
||||
}
|
||||
catch (NamespaceException ne)
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return dictionaryService.getSubTypes(baseType, true);
|
||||
}
|
||||
|
||||
LOGGER.warn("Ignoring invalid type pattern: " + typeDef);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private QName getQName(String type)
|
||||
{
|
||||
return QName.createQName(type, namespaceService);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ public class RetryingTransactionInterceptor extends TransactionAspectSupport imp
|
||||
final TransactionAttribute txnAttr = getTransactionAttributeSource().getTransactionAttribute(
|
||||
method, invocation.getThis().getClass());
|
||||
|
||||
final TransactionManager tm = determineTransactionManager(txnAttr);
|
||||
final TransactionManager tm = determineTransactionManager(txnAttr, null);
|
||||
|
||||
if (tm != null && !(tm instanceof PlatformTransactionManager))
|
||||
{
|
||||
|
||||
@@ -3,23 +3,30 @@
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="event2TypeDefExpander" class="org.alfresco.repo.event2.shared.TypeDefExpander">
|
||||
<constructor-arg ref="dictionaryService"/>
|
||||
<constructor-arg ref="namespaceService"/>
|
||||
</bean>
|
||||
|
||||
<!-- Event2 Filters -->
|
||||
<bean id="event2FilterRegistry" class="org.alfresco.repo.event2.filter.EventFilterRegistry"/>
|
||||
|
||||
<bean id="abstractNodeEventFilter" class="org.alfresco.repo.event2.filter.AbstractNodeEventFilter" abstract="true" init-method="init">
|
||||
<property name="dictionaryService" ref="dictionaryService"/>
|
||||
<property name="namespaceService" ref="namespaceService"/>
|
||||
<property name="typeDefExpander" ref="event2TypeDefExpander"/>
|
||||
</bean>
|
||||
|
||||
<bean id="event2NodeTypeFilter" class="org.alfresco.repo.event2.filter.NodeTypeFilter" parent="abstractNodeEventFilter">
|
||||
<constructor-arg value="${repo.event2.filter.nodeTypes}"/>
|
||||
<constructor-arg ref="dictionaryService"/>
|
||||
</bean>
|
||||
|
||||
<bean id="event2NodeAspectFilter" class="org.alfresco.repo.event2.filter.NodeAspectFilter" parent="abstractNodeEventFilter">
|
||||
<constructor-arg value="${repo.event2.filter.nodeAspects}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="event2NodePropertyFilter" class="org.alfresco.repo.event2.filter.NodePropertyFilter" parent="abstractNodeEventFilter"/>
|
||||
<bean id="event2NodePropertyFilter" class="org.alfresco.repo.event2.filter.NodePropertyFilter" parent="abstractNodeEventFilter">
|
||||
<constructor-arg value="${repo.event2.filter.nodeProperties}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="event2UserFilter" class="org.alfresco.repo.event2.filter.EventUserFilter">
|
||||
<constructor-arg value="${repo.event2.filter.users}"/>
|
||||
@@ -31,6 +38,16 @@
|
||||
</bean>
|
||||
<!-- End of Event2 Filters -->
|
||||
|
||||
<bean id="event2PropertyMapperFactory" class="org.alfresco.repo.event2.mapper.PropertyMapperFactory">
|
||||
<constructor-arg ref="event2TypeDefExpander"/>
|
||||
</bean>
|
||||
|
||||
<bean id="event2PropertyMapper" factory-bean="event2PropertyMapperFactory" factory-method="createPropertyMapper">
|
||||
<constructor-arg value="${repo.event2.mapper.enabled}"/>
|
||||
<constructor-arg value="${repo.event2.mapper.overrideDefaultProperties}"/>
|
||||
<constructor-arg value="${repo.event2.mapper.overrideReplacementText}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="baseEventGeneratorV2" abstract="true">
|
||||
<property name="policyComponent" ref="policyComponent"/>
|
||||
<property name="nodeService" ref="nodeService"/>
|
||||
@@ -53,6 +70,7 @@
|
||||
<property name="eventFilterRegistry" ref="event2FilterRegistry"/>
|
||||
<property name="namespaceService" ref="namespaceService"/>
|
||||
<property name="permissionService" ref="permissionService"/>
|
||||
<property name="propertyMapper" ref="event2PropertyMapper"/>
|
||||
</bean>
|
||||
|
||||
<bean id="baseEventSender" abstract="true">
|
||||
|
||||
@@ -1234,6 +1234,10 @@ repo.event2.filter.childAssocTypes=rn:rendition
|
||||
# Comma separated list of users which should be excluded
|
||||
# Note: username's case-sensitivity depends on the {user.name.caseSensitive} setting
|
||||
repo.event2.filter.users=
|
||||
repo.event2.filter.nodeProperties=
|
||||
repo.event2.mapper.enabled=true
|
||||
repo.event2.mapper.overrideDefaultProperties=
|
||||
repo.event2.mapper.overrideReplacementText=
|
||||
# Topic name
|
||||
repo.event2.topic.endpoint=amqp:topic:alfresco.repo.event2
|
||||
# Specifies the strategy for sending the events
|
||||
@@ -1393,4 +1397,4 @@ default.async.folder.items=1000
|
||||
# Default NodeSize Thread pool
|
||||
default.nodeSize.corePoolSize=5
|
||||
default.nodeSize.maximumPoolSize=10
|
||||
default.nodeSize.workQueueSize=100
|
||||
default.nodeSize.workQueueSize=100
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 2025 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.event2;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.alfresco.repo.event2.shared.CSVStringToListParser;
|
||||
|
||||
public class CSVStringToListParserUnitTest
|
||||
{
|
||||
@Test
|
||||
public void shouldIgnoreEmptySpacesAndNoneValueAndTemplateStringsAndParseTheRest()
|
||||
{
|
||||
String userInputCSV = "a,,none,2,${test}, ,*";
|
||||
|
||||
List<String> result = CSVStringToListParser.parse(userInputCSV);
|
||||
|
||||
List<String> expected = List.of("a", "2", "*");
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2025 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -35,6 +35,10 @@ import static org.mockito.Mockito.when;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.model.ForumModel;
|
||||
import org.alfresco.model.RenditionModel;
|
||||
@@ -43,14 +47,12 @@ import org.alfresco.repo.event2.filter.EventUserFilter;
|
||||
import org.alfresco.repo.event2.filter.NodeAspectFilter;
|
||||
import org.alfresco.repo.event2.filter.NodePropertyFilter;
|
||||
import org.alfresco.repo.event2.filter.NodeTypeFilter;
|
||||
import org.alfresco.repo.event2.shared.TypeDefExpander;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.namespace.NamespaceException;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.OneToManyHashBiMap;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
/**
|
||||
* Tests event filters.
|
||||
@@ -78,32 +80,32 @@ public class EventFilterUnitTest
|
||||
|
||||
namespaceService = new MockNamespaceServiceImpl();
|
||||
namespaceService.registerNamespace(NamespaceService.SYSTEM_MODEL_PREFIX,
|
||||
NamespaceService.SYSTEM_MODEL_1_0_URI);
|
||||
NamespaceService.SYSTEM_MODEL_1_0_URI);
|
||||
namespaceService.registerNamespace(NamespaceService.CONTENT_MODEL_PREFIX,
|
||||
NamespaceService.CONTENT_MODEL_1_0_URI);
|
||||
NamespaceService.CONTENT_MODEL_1_0_URI);
|
||||
namespaceService.registerNamespace(NamespaceService.FORUMS_MODEL_PREFIX,
|
||||
NamespaceService.FORUMS_MODEL_1_0_URI);
|
||||
NamespaceService.FORUMS_MODEL_1_0_URI);
|
||||
namespaceService.registerNamespace(NamespaceService.RENDITION_MODEL_PREFIX,
|
||||
NamespaceService.RENDITION_MODEL_1_0_URI);
|
||||
NamespaceService.RENDITION_MODEL_1_0_URI);
|
||||
namespaceService.registerNamespace(ContentModel.USER_MODEL_PREFIX,
|
||||
ContentModel.USER_MODEL_URI);
|
||||
|
||||
propertyFilter = new NodePropertyFilter();
|
||||
propertyFilter.setNamespaceService(namespaceService);
|
||||
propertyFilter.setDictionaryService(dictionaryService);
|
||||
TypeDefExpander typeDefExpander = new TypeDefExpander(dictionaryService, namespaceService);
|
||||
|
||||
propertyFilter = new NodePropertyFilter("usr:password");
|
||||
propertyFilter.setTypeDefExpander(typeDefExpander);
|
||||
propertyFilter.init();
|
||||
|
||||
typeFilter = new NodeTypeFilter("sys:*, fm:*, cm:thumbnail");
|
||||
typeFilter.setNamespaceService(namespaceService);
|
||||
typeFilter.setDictionaryService(dictionaryService);
|
||||
typeFilter = new NodeTypeFilter("sys:*, fm:*, cm:thumbnail", dictionaryService);
|
||||
typeFilter.setTypeDefExpander(typeDefExpander);
|
||||
typeFilter.init();
|
||||
|
||||
aspectFilter = new NodeAspectFilter("cm:workingcopy");
|
||||
aspectFilter.setNamespaceService(namespaceService);
|
||||
aspectFilter.setDictionaryService(dictionaryService);
|
||||
aspectFilter.setTypeDefExpander(typeDefExpander);
|
||||
aspectFilter.init();
|
||||
|
||||
childAssociationTypeFilter = new ChildAssociationTypeFilter("rn:rendition");
|
||||
childAssociationTypeFilter.setNamespaceService(namespaceService);
|
||||
childAssociationTypeFilter.setDictionaryService(dictionaryService);
|
||||
childAssociationTypeFilter.setTypeDefExpander(typeDefExpander);
|
||||
childAssociationTypeFilter.init();
|
||||
|
||||
caseInsensitive_userFilter = new EventUserFilter("System, john.doe, null", false);
|
||||
@@ -114,10 +116,12 @@ public class EventFilterUnitTest
|
||||
public void nodePropertyFilter()
|
||||
{
|
||||
assertTrue("System properties are excluded by default.",
|
||||
propertyFilter.isExcluded(ContentModel.PROP_NODE_UUID));
|
||||
propertyFilter.isExcluded(ContentModel.PROP_NODE_UUID));
|
||||
|
||||
assertTrue("System properties are excluded by default.",
|
||||
propertyFilter.isExcluded(ContentModel.PROP_NODE_DBID));
|
||||
propertyFilter.isExcluded(ContentModel.PROP_NODE_DBID));
|
||||
|
||||
assertTrue("User configured properties are excluded.", propertyFilter.isExcluded(ContentModel.PROP_PASSWORD));
|
||||
|
||||
assertFalse("Property cascadeTx is not excluded", propertyFilter.isExcluded(ContentModel.PROP_CASCADE_TX));
|
||||
assertFalse("Property cascadeCRC is not excluded", propertyFilter.isExcluded(ContentModel.PROP_CASCADE_CRC));
|
||||
@@ -129,16 +133,16 @@ public class EventFilterUnitTest
|
||||
public void nodeTypeFilter()
|
||||
{
|
||||
assertTrue("Thumbnail node type should have been filtered.",
|
||||
typeFilter.isExcluded(ContentModel.TYPE_THUMBNAIL));
|
||||
typeFilter.isExcluded(ContentModel.TYPE_THUMBNAIL));
|
||||
|
||||
assertTrue("System folder node types are excluded by default.",
|
||||
typeFilter.isExcluded(ContentModel.TYPE_SYSTEM_FOLDER));
|
||||
typeFilter.isExcluded(ContentModel.TYPE_SYSTEM_FOLDER));
|
||||
|
||||
assertTrue("System node type should have been filtered (sys:*).",
|
||||
typeFilter.isExcluded(QName.createQName("sys:testSomeSystemType", namespaceService)));
|
||||
typeFilter.isExcluded(QName.createQName("sys:testSomeSystemType", namespaceService)));
|
||||
|
||||
assertTrue("Forum node type should have been filtered (fm:*).",
|
||||
typeFilter.isExcluded(ForumModel.TYPE_POST));
|
||||
typeFilter.isExcluded(ForumModel.TYPE_POST));
|
||||
|
||||
assertFalse(typeFilter.isExcluded(ContentModel.TYPE_FOLDER));
|
||||
}
|
||||
@@ -147,7 +151,7 @@ public class EventFilterUnitTest
|
||||
public void nodeAspectFilter()
|
||||
{
|
||||
assertTrue("Working copy aspect should have been filtered.",
|
||||
aspectFilter.isExcluded(ContentModel.ASPECT_WORKING_COPY));
|
||||
aspectFilter.isExcluded(ContentModel.ASPECT_WORKING_COPY));
|
||||
|
||||
assertFalse(aspectFilter.isExcluded(ContentModel.ASPECT_TITLED));
|
||||
}
|
||||
@@ -160,41 +164,41 @@ public class EventFilterUnitTest
|
||||
|
||||
assertFalse(childAssociationTypeFilter.isExcluded(ContentModel.ASSOC_CONTAINS));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void userFilter_case_insensitive()
|
||||
{
|
||||
assertTrue("System user should have been filtered.",
|
||||
caseInsensitive_userFilter.isExcluded("System"));
|
||||
caseInsensitive_userFilter.isExcluded("System"));
|
||||
|
||||
assertTrue("System user should have been filtered (case-insensitive).",
|
||||
caseInsensitive_userFilter.isExcluded("SYSTEM"));
|
||||
caseInsensitive_userFilter.isExcluded("SYSTEM"));
|
||||
|
||||
assertTrue("'null' user should have been filtered.",
|
||||
caseInsensitive_userFilter.isExcluded("null"));
|
||||
caseInsensitive_userFilter.isExcluded("null"));
|
||||
|
||||
assertTrue("john.doe user should have been filtered.",
|
||||
caseInsensitive_userFilter.isExcluded("John.Doe"));
|
||||
caseInsensitive_userFilter.isExcluded("John.Doe"));
|
||||
|
||||
assertFalse("'jane.doe' user should not have been filtered.",
|
||||
caseInsensitive_userFilter.isExcluded("jane.doe"));
|
||||
caseInsensitive_userFilter.isExcluded("jane.doe"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void userFilter_case_sensitive()
|
||||
{
|
||||
assertFalse("'system' user should not have been filtered.",
|
||||
caseSensitive_userFilter.isExcluded("system"));
|
||||
caseSensitive_userFilter.isExcluded("system"));
|
||||
assertTrue("'System' user should have been filtered.",
|
||||
caseSensitive_userFilter.isExcluded("System"));
|
||||
caseSensitive_userFilter.isExcluded("System"));
|
||||
|
||||
assertFalse("'John.Doe' user should not have been filtered.",
|
||||
caseSensitive_userFilter.isExcluded("John.Doe"));
|
||||
caseSensitive_userFilter.isExcluded("John.Doe"));
|
||||
assertTrue("'john.doe' user should have been filtered.",
|
||||
caseSensitive_userFilter.isExcluded("john.doe"));
|
||||
caseSensitive_userFilter.isExcluded("john.doe"));
|
||||
|
||||
assertFalse("'jane.doe' user should not have been filtered.",
|
||||
caseSensitive_userFilter.isExcluded("jane.doe"));
|
||||
caseSensitive_userFilter.isExcluded("jane.doe"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 2025 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.event2;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.event2.mapper.PropertyMapper;
|
||||
import org.alfresco.repo.event2.mapper.ReplaceSensitivePropertyWithTextMapper;
|
||||
import org.alfresco.repo.transfer.TransferModel;
|
||||
|
||||
public class PropertyMapperUnitTest
|
||||
{
|
||||
private static final String DEFAULT_REPLACEMENT_TEXT = "SENSITIVE_DATA_REMOVED";
|
||||
private static final String USER_CONFIGURED_REPLACEMENT_TEXT = "HIDDEN_BY_SECURITY_CONFIG";
|
||||
|
||||
private final PropertyMapper defaultPropertyMapper = new ReplaceSensitivePropertyWithTextMapper(null,null);
|
||||
private final PropertyMapper userConfiguredpropertyMapper = new ReplaceSensitivePropertyWithTextMapper(
|
||||
Set.of(ContentModel.PROP_PASSWORD, TransferModel.PROP_PASSWORD),
|
||||
USER_CONFIGURED_REPLACEMENT_TEXT
|
||||
);
|
||||
|
||||
@Test
|
||||
public void shouldReplacePropertyValueWhenItsOneOfTheDefaultSensitivePropertiesWhenUsingDefaultConfig()
|
||||
{
|
||||
assertEquals(DEFAULT_REPLACEMENT_TEXT, defaultPropertyMapper.map(ContentModel.PROP_PASSWORD, "test_pass"));
|
||||
assertEquals(DEFAULT_REPLACEMENT_TEXT, defaultPropertyMapper.map(ContentModel.PROP_SALT, UUID.randomUUID().toString()));
|
||||
assertEquals(DEFAULT_REPLACEMENT_TEXT, defaultPropertyMapper.map(ContentModel.PROP_PASSWORD_HASH, "r4nD0M_h4sH"));
|
||||
assertEquals(DEFAULT_REPLACEMENT_TEXT, defaultPropertyMapper.map(TransferModel.PROP_PASSWORD, "pyramid"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotReplacePropertyValueWhenItsNotOneOfTheDefaultSensitivePropertiesWhenUsingDefaultConfig()
|
||||
{
|
||||
assertEquals("Bob", defaultPropertyMapper.map(ContentModel.PROP_USERNAME, "Bob"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReplacePropertyValueWhenItsOneOfTheDefaultSensitivePropertiesWhenUsingUserConfig()
|
||||
{
|
||||
assertEquals(USER_CONFIGURED_REPLACEMENT_TEXT, userConfiguredpropertyMapper.map(ContentModel.PROP_PASSWORD, "test_pass"));
|
||||
|
||||
assertEquals(USER_CONFIGURED_REPLACEMENT_TEXT, userConfiguredpropertyMapper.map(TransferModel.PROP_PASSWORD, "pyramid"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotReplacePropertyValueWhenItsNotOneOfTheDefaultSensitivePropertiesWhenUsingUserConfig()
|
||||
{
|
||||
String randomUuid = UUID.randomUUID().toString();
|
||||
assertEquals(randomUuid, userConfiguredpropertyMapper.map(ContentModel.PROP_SALT, randomUuid));
|
||||
assertEquals("r4nD0M_h4sH", userConfiguredpropertyMapper.map(ContentModel.PROP_PASSWORD_HASH, "r4nD0M_h4sH"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 2025 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.event2;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.event2.shared.QNameMatcher;
|
||||
import org.alfresco.repo.transfer.TransferModel;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
public class QNameMatcherUnitTest
|
||||
{
|
||||
@Test
|
||||
public void shouldMatchOnlyQNamesFromUserModelURI()
|
||||
{
|
||||
QNameMatcher qNameMatcher = new QNameMatcher(Set.of(QName.createQName(ContentModel.USER_MODEL_URI, "*")));
|
||||
|
||||
assertTrue(qNameMatcher.isMatching(ContentModel.PROP_USER_USERNAME));
|
||||
assertTrue(qNameMatcher.isMatching(ContentModel.TYPE_USER));
|
||||
assertFalse(qNameMatcher.isMatching(ContentModel.PROP_TITLE));
|
||||
assertFalse(qNameMatcher.isMatching(TransferModel.PROP_USERNAME));
|
||||
assertFalse(qNameMatcher.isMatching(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldOnlyMatchSpecificQName()
|
||||
{
|
||||
QNameMatcher qNameMatcher = new QNameMatcher(Set.of(ContentModel.PROP_USER_USERNAME));
|
||||
|
||||
assertTrue(qNameMatcher.isMatching(ContentModel.PROP_USER_USERNAME));
|
||||
assertFalse(qNameMatcher.isMatching(ContentModel.PROP_NAME));
|
||||
assertFalse(qNameMatcher.isMatching(ContentModel.PROP_USERNAME));
|
||||
assertFalse(qNameMatcher.isMatching(TransferModel.PROP_USERNAME));
|
||||
assertFalse(qNameMatcher.isMatching(null));
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2025 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -30,12 +30,15 @@ import org.junit.runners.Suite;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses({ EventFilterUnitTest.class,
|
||||
EventConsolidatorUnitTest.class,
|
||||
EventJSONSchemaUnitTest.class,
|
||||
EnqueuingEventSenderUnitTest.class,
|
||||
NodeResourceHelperUnitTest.class
|
||||
@SuiteClasses({EventFilterUnitTest.class,
|
||||
EventConsolidatorUnitTest.class,
|
||||
EventJSONSchemaUnitTest.class,
|
||||
EnqueuingEventSenderUnitTest.class,
|
||||
NodeResourceHelperUnitTest.class,
|
||||
PropertyMapperUnitTest.class,
|
||||
QNameMatcherUnitTest.class,
|
||||
CSVStringToListParserUnitTest.class,
|
||||
TypeDefExpanderUnitTest.class
|
||||
})
|
||||
public class RepoEvent2UnitSuite
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 2025 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.event2;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.model.DataListModel;
|
||||
import org.alfresco.repo.event2.shared.TypeDefExpander;
|
||||
import org.alfresco.repo.transfer.TransferModel;
|
||||
import org.alfresco.repo.workflow.WorkflowModel;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
public class TypeDefExpanderUnitTest
|
||||
{
|
||||
private DictionaryService dictionaryService;
|
||||
private NamespaceService namespaceService;
|
||||
private TypeDefExpander typeDefExpander;
|
||||
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
dictionaryService = mock(DictionaryService.class);
|
||||
namespaceService = mock(NamespaceService.class);
|
||||
typeDefExpander = new TypeDefExpander(dictionaryService, namespaceService);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandWithValidType()
|
||||
{
|
||||
String input = "usr:username";
|
||||
when(namespaceService.getNamespaceURI("usr")).thenReturn(ContentModel.USER_MODEL_URI);
|
||||
|
||||
Collection<QName> result = typeDefExpander.expand(input);
|
||||
|
||||
QName expected = ContentModel.PROP_USER_USERNAME;
|
||||
assertEquals(expected, result.iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandWithValidTypeIncludingSubtypes()
|
||||
{
|
||||
String input = "cm:content include_subtypes";
|
||||
when(namespaceService.getNamespaceURI("cm")).thenReturn(NamespaceService.CONTENT_MODEL_1_0_URI);
|
||||
Set<QName> subtypes = Set.of(TransferModel.TYPE_TRANSFER_RECORD, DataListModel.TYPE_EVENT, WorkflowModel.TYPE_TASK);
|
||||
when(dictionaryService.getSubTypes(ContentModel.TYPE_CONTENT, true)).thenReturn(subtypes);
|
||||
|
||||
Collection<QName> result = typeDefExpander.expand(input);
|
||||
|
||||
assertEquals(subtypes, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandWithInvalidTypes()
|
||||
{
|
||||
Set<String> input = Stream.of(null, " ", "none", "${test.prop}").collect(Collectors.toSet());
|
||||
|
||||
Collection<QName> result = typeDefExpander.expand(input);
|
||||
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@ import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.ContextCustomizerFactories;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
@@ -46,6 +47,7 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration({"classpath:alfresco/application-context.xml"})
|
||||
@ContextCustomizerFactories(factories = {}, mergeMode = ContextCustomizerFactories.MergeMode.REPLACE_DEFAULTS)
|
||||
public abstract class BaseSpringTest extends TestCase
|
||||
{
|
||||
public Log logger = LogFactory.getLog(getClass().getName());
|
||||
|
||||
@@ -463,4 +463,4 @@ logger.alfresco-repo-thumbnail-ThumbnailServiceImplTest.name=org.alfresco.repo.t
|
||||
logger.alfresco-repo-thumbnail-ThumbnailServiceImplTest.level=debug
|
||||
|
||||
logger.alfresco-repo-rendition2-RenditionService2Impl.name=org.alfresco.repo.rendition2.RenditionService2Impl
|
||||
logger.alfresco-repo-rendition2-RenditionService2Impl.level=debug
|
||||
logger.alfresco-repo-rendition2-RenditionService2Impl.level=debug
|
||||
|
||||
@@ -9,7 +9,7 @@ services:
|
||||
ports:
|
||||
- "8090:8090"
|
||||
postgres:
|
||||
image: postgres:15.4
|
||||
image: postgres:16.6
|
||||
profiles: ["default", "with-transform-core-aio", "postgres", "with-mtls-transform-core-aio", "with-sso"]
|
||||
environment:
|
||||
- POSTGRES_PASSWORD=alfresco
|
||||
@@ -59,7 +59,7 @@ services:
|
||||
CLIENT_SSL_TRUST_STORE_TYPE: "JCEKS"
|
||||
keycloak:
|
||||
profiles: ["with-sso"]
|
||||
image: quay.io/keycloak/keycloak:26.0.7
|
||||
image: quay.io/keycloak/keycloak:26.1.0
|
||||
environment:
|
||||
- KC_BOOTSTRAP_ADMIN_USERNAME=admin
|
||||
- KC_BOOTSTRAP_ADMIN_PASSWORD=admin
|
||||
|
||||
Reference in New Issue
Block a user