mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-09-24 14:32:01 +00:00
Compare commits
58 Commits
dependabot
...
25.3.0.42
Author | SHA1 | Date | |
---|---|---|---|
|
82d316d802 | ||
|
1840d1056d | ||
|
334e8c84df | ||
|
24309cf4b6 | ||
|
2d28742a94 | ||
|
d6503ac1de | ||
|
73ef1ed9ff | ||
|
d3bc9e2b60 | ||
|
174186d1ff | ||
|
57331afe8f | ||
|
7c87595b0c | ||
|
b7191b175e | ||
|
39b19d1ceb | ||
|
9e23b99078 | ||
|
ac36ac07e8 | ||
|
cc10339577 | ||
|
8aa975fbc3 | ||
|
01620b75ff | ||
|
9327218f17 | ||
|
b57373fbe3 | ||
|
613fb458b9 | ||
|
31cd97b9d2 | ||
|
255fe46c8e | ||
|
88d32748b1 | ||
|
90e1522a56 | ||
|
7e61befc21 | ||
|
be6dc14330 | ||
|
ab4bc1af9f | ||
|
eaec23ae7a | ||
|
8ff727c95d | ||
|
48475fdfaa | ||
|
812959be2e | ||
|
5b8c52db67 | ||
|
20c42b6561 | ||
|
52dfea9b21 | ||
|
d04dada44e | ||
|
2e85de7c81 | ||
|
42324368e5 | ||
|
8d885220d8 | ||
|
6367f5304d | ||
|
f17b309c27 | ||
|
bb2cc1765d | ||
|
d20e8ee158 | ||
|
254193f9aa | ||
|
4293f21618 | ||
|
e0eb43c479 | ||
|
f1bbb6cce7 | ||
|
e6e2a2d8ac | ||
|
c2cfcdc35a | ||
|
6b2ac86b1d | ||
|
8b212dc4cf | ||
|
e2c357c1e0 | ||
|
4a024e510d | ||
|
3f75c9b15f | ||
|
96f94a98be | ||
|
bfc0445aeb | ||
|
977f6f12d4 | ||
|
626640ddc7 |
38
.github/workflows/ci.yml
vendored
38
.github/workflows/ci.yml
vendored
@@ -38,7 +38,7 @@ jobs:
|
|||||||
!contains(github.event.head_commit.message, '[skip tests]') &&
|
!contains(github.event.head_commit.message, '[skip tests]') &&
|
||||||
!contains(github.event.head_commit.message, '[force')
|
!contains(github.event.head_commit.message, '[force')
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
@@ -61,7 +61,7 @@ jobs:
|
|||||||
!contains(github.event.head_commit.message, '[skip tests]') &&
|
!contains(github.event.head_commit.message, '[skip tests]') &&
|
||||||
!contains(github.event.head_commit.message, '[force')
|
!contains(github.event.head_commit.message, '[force')
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
||||||
@@ -84,7 +84,7 @@ jobs:
|
|||||||
!contains(github.event.head_commit.message, '[skip tests]') &&
|
!contains(github.event.head_commit.message, '[skip tests]') &&
|
||||||
!contains(github.event.head_commit.message, '[force')
|
!contains(github.event.head_commit.message, '[force')
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
||||||
@@ -173,7 +173,7 @@ jobs:
|
|||||||
testModule: mmt
|
testModule: mmt
|
||||||
testAttributes: "-Dtest=AllMmtUnitTestSuite"
|
testAttributes: "-Dtest=AllMmtUnitTestSuite"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
||||||
@@ -210,7 +210,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
REQUIRES_INSTALLED_ARTIFACTS: true
|
REQUIRES_INSTALLED_ARTIFACTS: true
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
||||||
@@ -245,7 +245,7 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
version: ['10.5', '10.6']
|
version: ['10.5', '10.6']
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
||||||
@@ -272,7 +272,7 @@ jobs:
|
|||||||
!contains(github.event.head_commit.message, '[skip tests]') &&
|
!contains(github.event.head_commit.message, '[skip tests]') &&
|
||||||
!contains(github.event.head_commit.message, '[force')
|
!contains(github.event.head_commit.message, '[force')
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
||||||
@@ -299,7 +299,7 @@ jobs:
|
|||||||
!contains(github.event.head_commit.message, '[skip tests]') &&
|
!contains(github.event.head_commit.message, '[skip tests]') &&
|
||||||
!contains(github.event.head_commit.message, '[force')
|
!contains(github.event.head_commit.message, '[force')
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
||||||
@@ -325,7 +325,7 @@ jobs:
|
|||||||
!contains(github.event.head_commit.message, '[skip tests]') &&
|
!contains(github.event.head_commit.message, '[skip tests]') &&
|
||||||
!contains(github.event.head_commit.message, '[force')
|
!contains(github.event.head_commit.message, '[force')
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
||||||
@@ -351,7 +351,7 @@ jobs:
|
|||||||
!contains(github.event.head_commit.message, '[skip tests]') &&
|
!contains(github.event.head_commit.message, '[skip tests]') &&
|
||||||
!contains(github.event.head_commit.message, '[force')
|
!contains(github.event.head_commit.message, '[force')
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
||||||
@@ -377,7 +377,7 @@ jobs:
|
|||||||
!contains(github.event.head_commit.message, '[skip tests]') &&
|
!contains(github.event.head_commit.message, '[skip tests]') &&
|
||||||
!contains(github.event.head_commit.message, '[force')
|
!contains(github.event.head_commit.message, '[force')
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
||||||
@@ -401,7 +401,7 @@ jobs:
|
|||||||
!contains(github.event.head_commit.message, '[skip tests]') &&
|
!contains(github.event.head_commit.message, '[skip tests]') &&
|
||||||
!contains(github.event.head_commit.message, '[force')
|
!contains(github.event.head_commit.message, '[force')
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
||||||
@@ -457,7 +457,7 @@ jobs:
|
|||||||
disabledHostnameVerification: false
|
disabledHostnameVerification: false
|
||||||
mvn-options: '-Dencryption.ssl.keystore.location=${CI_WORKSPACE}/keystores/alfresco/alfresco.keystore -Dencryption.ssl.truststore.location=${CI_WORKSPACE}/keystores/alfresco/alfresco.truststore'
|
mvn-options: '-Dencryption.ssl.keystore.location=${CI_WORKSPACE}/keystores/alfresco/alfresco.keystore -Dencryption.ssl.truststore.location=${CI_WORKSPACE}/keystores/alfresco/alfresco.truststore'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
||||||
@@ -527,7 +527,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
REQUIRES_LOCAL_IMAGES: true
|
REQUIRES_LOCAL_IMAGES: true
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
||||||
@@ -566,7 +566,7 @@ jobs:
|
|||||||
!contains(github.event.head_commit.message, '[skip tests]') &&
|
!contains(github.event.head_commit.message, '[skip tests]') &&
|
||||||
!contains(github.event.head_commit.message, '[force')
|
!contains(github.event.head_commit.message, '[force')
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
||||||
@@ -596,7 +596,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
REQUIRES_INSTALLED_ARTIFACTS: true
|
REQUIRES_INSTALLED_ARTIFACTS: true
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
||||||
@@ -628,7 +628,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
REQUIRES_INSTALLED_ARTIFACTS: true
|
REQUIRES_INSTALLED_ARTIFACTS: true
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
||||||
@@ -656,7 +656,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
REQUIRES_LOCAL_IMAGES: true
|
REQUIRES_LOCAL_IMAGES: true
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
||||||
@@ -702,7 +702,7 @@ jobs:
|
|||||||
!contains(github.event.head_commit.message, '[skip tests]') &&
|
!contains(github.event.head_commit.message, '[skip tests]') &&
|
||||||
!contains(github.event.head_commit.message, '[force]')
|
!contains(github.event.head_commit.message, '[force]')
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
|
||||||
|
4
.github/workflows/master_release.yml
vendored
4
.github/workflows/master_release.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
|||||||
!contains(github.event.head_commit.message, '[no release]') &&
|
!contains(github.event.head_commit.message, '[no release]') &&
|
||||||
github.event_name != 'pull_request'
|
github.event_name != 'pull_request'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
@@ -60,7 +60,7 @@ jobs:
|
|||||||
!contains(github.event.head_commit.message, '[no downstream]') &&
|
!contains(github.event.head_commit.message, '[no downstream]') &&
|
||||||
github.event_name != 'pull_request'
|
github.event_name != 'pull_request'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
|
||||||
|
2
.github/workflows/precommit_formatter.yml
vendored
2
.github/workflows/precommit_formatter.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: contains(github.event.head_commit.message, '[reformat code]')
|
if: contains(github.event.head_commit.message, '[reformat code]')
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- name: Set up Python ${{ inputs.python-version }}
|
- name: Set up Python ${{ inputs.python-version }}
|
||||||
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
||||||
with:
|
with:
|
||||||
|
@@ -1242,7 +1242,7 @@
|
|||||||
"filename": "repository/src/main/resources/alfresco/repository.properties",
|
"filename": "repository/src/main/resources/alfresco/repository.properties",
|
||||||
"hashed_secret": "1459a56410378e4d3ab470eff570e5eae1742762",
|
"hashed_secret": "1459a56410378e4d3ab470eff570e5eae1742762",
|
||||||
"is_verified": false,
|
"is_verified": false,
|
||||||
"line_number": 312,
|
"line_number": 314,
|
||||||
"is_secret": false
|
"is_secret": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1250,7 +1250,7 @@
|
|||||||
"filename": "repository/src/main/resources/alfresco/repository.properties",
|
"filename": "repository/src/main/resources/alfresco/repository.properties",
|
||||||
"hashed_secret": "84551ae5442affc9f1a2d3b4c86ae8b24860149d",
|
"hashed_secret": "84551ae5442affc9f1a2d3b4c86ae8b24860149d",
|
||||||
"is_verified": false,
|
"is_verified": false,
|
||||||
"line_number": 771,
|
"line_number": 773,
|
||||||
"is_secret": false
|
"is_secret": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -1845,5 +1845,5 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"generated_at": "2025-06-09T16:43:14Z"
|
"generated_at": "2025-07-23T08:25:11Z"
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
|
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@@ -43,7 +43,7 @@ import com.github.dockerjava.core.command.LogContainerResultCallback;
|
|||||||
import com.github.dockerjava.netty.NettyDockerCmdExecFactory;
|
import com.github.dockerjava.netty.NettyDockerCmdExecFactory;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.apache.commons.lang.SystemUtils;
|
import org.apache.commons.lang3.SystemUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@@ -37,7 +37,7 @@ import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPr
|
|||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
@@ -56,7 +56,7 @@ import org.alfresco.test.AlfrescoTest;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Add Relationship tests
|
* Add Relationship tests
|
||||||
*
|
*
|
||||||
* @author Kavit Shah
|
* @author Kavit Shah
|
||||||
*/
|
*/
|
||||||
public class AddRelationshipTests extends BaseRMRestTest
|
public class AddRelationshipTests extends BaseRMRestTest
|
||||||
|
@@ -45,7 +45,7 @@ import java.time.Instant;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.http.HttpEntity;
|
import org.apache.http.HttpEntity;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.HttpStatus;
|
import org.apache.http.HttpStatus;
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
@@ -15,6 +15,13 @@
|
|||||||
<parameter property="end" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
<parameter property="end" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
</parameterMap>
|
</parameterMap>
|
||||||
|
|
||||||
|
<parameterMap id="parameter_NodeIdsWhichReferenceContentUrl" type="map">
|
||||||
|
<parameter property="contentUrlShort" jdbcType="VARCHAR" javaType="java.lang.String"/>
|
||||||
|
<parameter property="contentUrlCrc" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
|
<parameter property="localName" jdbcType="VARCHAR" javaType="java.lang.String"/>
|
||||||
|
<parameter property="uri" jdbcType="VARCHAR" javaType="java.lang.String"/>
|
||||||
|
</parameterMap>
|
||||||
|
|
||||||
<resultMap id="result_NodeRefEntity" type="org.alfresco.module.org_alfresco_module_rm.query.NodeRefEntity">
|
<resultMap id="result_NodeRefEntity" type="org.alfresco.module.org_alfresco_module_rm.query.NodeRefEntity">
|
||||||
<result property="row" column="row" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
<result property="row" column="row" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
<result property="protocol" column="protocol" jdbcType="VARCHAR" javaType="java.lang.String"/>
|
<result property="protocol" column="protocol" jdbcType="VARCHAR" javaType="java.lang.String"/>
|
||||||
@@ -55,18 +62,21 @@
|
|||||||
|
|
||||||
<!-- Get list of node ids which reference given content url -->
|
<!-- Get list of node ids which reference given content url -->
|
||||||
<select id="select_NodeIdsWhichReferenceContentUrl"
|
<select id="select_NodeIdsWhichReferenceContentUrl"
|
||||||
parameterType="ContentUrl"
|
parameterMap="parameter_NodeIdsWhichReferenceContentUrl"
|
||||||
resultMap="result_NodeIds">
|
resultMap="result_NodeIds">
|
||||||
select
|
select
|
||||||
p.node_id
|
p.node_id
|
||||||
from
|
from
|
||||||
alf_content_url cu
|
alf_content_url cu
|
||||||
LEFT OUTER JOIN alf_content_data cd ON (cd.content_url_id = cu.id)
|
left outer join alf_content_data cd ON (cd.content_url_id = cu.id)
|
||||||
LEFT OUTER JOIN alf_node_properties p ON (p.long_value = cd.id)
|
left outer join alf_node_properties p ON (p.long_value = cd.id)
|
||||||
WHERE
|
left outer join alf_qname q ON (q.id = p.qname_id)
|
||||||
content_url_short = #{contentUrlShort} and
|
left outer join alf_namespace n ON (n.id = q.ns_id)
|
||||||
content_url_crc = #{contentUrlCrc}
|
where
|
||||||
|
cu.content_url_short = ? and
|
||||||
|
cu.content_url_crc = ? and
|
||||||
|
q.local_name = ? and
|
||||||
|
n.uri = ?
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="select_RecordFoldersWithSchedules"
|
<select id="select_RecordFoldersWithSchedules"
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
@@ -39,6 +39,7 @@ import org.apache.commons.logging.Log;
|
|||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.mybatis.spring.SqlSessionTemplate;
|
import org.mybatis.spring.SqlSessionTemplate;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||||
import org.alfresco.repo.domain.contentdata.ContentUrlEntity;
|
import org.alfresco.repo.domain.contentdata.ContentUrlEntity;
|
||||||
import org.alfresco.repo.domain.node.NodeDAO;
|
import org.alfresco.repo.domain.node.NodeDAO;
|
||||||
@@ -191,13 +192,19 @@ public class RecordsManagementQueryDAOImpl implements RecordsManagementQueryDAO,
|
|||||||
ContentUrlEntity contentUrlEntity = new ContentUrlEntity();
|
ContentUrlEntity contentUrlEntity = new ContentUrlEntity();
|
||||||
contentUrlEntity.setContentUrl(contentUrl.toLowerCase());
|
contentUrlEntity.setContentUrl(contentUrl.toLowerCase());
|
||||||
|
|
||||||
|
Map<String, Object> params = new HashMap<>(4);
|
||||||
|
params.put("contentUrlShort", contentUrlEntity.getContentUrlShort());
|
||||||
|
params.put("contentUrlCrc", contentUrlEntity.getContentUrlCrc());
|
||||||
|
params.put("localName", ContentModel.PROP_CONTENT.getLocalName());
|
||||||
|
params.put("uri", ContentModel.PROP_CONTENT.getNamespaceURI());
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
logger.debug("Executing query " + SELECT_NODE_IDS_WHICH_REFERENCE_CONTENT_URL);
|
logger.debug("Executing query " + SELECT_NODE_IDS_WHICH_REFERENCE_CONTENT_URL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all the node ids which reference the given content url
|
// Get all the node ids which reference the given content url
|
||||||
List<Long> nodeIds = template.selectList(SELECT_NODE_IDS_WHICH_REFERENCE_CONTENT_URL, contentUrlEntity);
|
List<Long> nodeIds = template.selectList(SELECT_NODE_IDS_WHICH_REFERENCE_CONTENT_URL, params);
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
|
@@ -36,6 +36,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
import org.springframework.context.ApplicationListener;
|
import org.springframework.context.ApplicationListener;
|
||||||
import org.springframework.context.event.ContextRefreshedEvent;
|
import org.springframework.context.event.ContextRefreshedEvent;
|
||||||
|
import org.springframework.dao.ConcurrencyFailureException;
|
||||||
import org.springframework.extensions.webscripts.ui.common.StringUtils;
|
import org.springframework.extensions.webscripts.ui.common.StringUtils;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
@@ -649,8 +650,8 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
catch (DuplicateChildNodeNameException ex)
|
catch (DuplicateChildNodeNameException ex)
|
||||||
{
|
{
|
||||||
// the group was concurrently created
|
// Rethrow as ConcurrencyFailureException so that is can be retried and linked to the group created by the concurrent transaction
|
||||||
group = authorityService.getName(AuthorityType.GROUP, groupShortName);
|
throw new ConcurrencyFailureException("IPR group creation failed due to concurrent duplicate group name creation: " + groupShortName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return group;
|
return group;
|
||||||
|
@@ -29,14 +29,23 @@ package org.alfresco.module.org_alfresco_module_rm.test.legacy.service;
|
|||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.springframework.dao.ConcurrencyFailureException;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
|
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
|
||||||
|
import org.alfresco.query.PagingRequest;
|
||||||
|
import org.alfresco.query.PagingResults;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||||
import org.alfresco.repo.site.SiteModel;
|
import org.alfresco.repo.site.SiteModel;
|
||||||
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.security.AccessPermission;
|
||||||
import org.alfresco.service.cmr.security.AccessStatus;
|
import org.alfresco.service.cmr.security.AccessStatus;
|
||||||
|
import org.alfresco.service.cmr.security.AuthorityType;
|
||||||
import org.alfresco.service.cmr.site.SiteService;
|
import org.alfresco.service.cmr.site.SiteService;
|
||||||
import org.alfresco.service.cmr.site.SiteVisibility;
|
import org.alfresco.service.cmr.site.SiteVisibility;
|
||||||
import org.alfresco.util.GUID;
|
import org.alfresco.util.GUID;
|
||||||
@@ -206,7 +215,8 @@ public class ExtendedSecurityServiceImplTest extends BaseRMTestCase
|
|||||||
final NodeRef record = doTestInTransaction(new Test<NodeRef>() {
|
final NodeRef record = doTestInTransaction(new Test<NodeRef>() {
|
||||||
public NodeRef run() throws Exception
|
public NodeRef run() throws Exception
|
||||||
{
|
{
|
||||||
NodeRef record = fileFolderService.create(documentLibrary, GUID.generate(), ContentModel.TYPE_CONTENT).getNodeRef();
|
NodeRef record = fileFolderService.create(documentLibrary, GUID.generate(), ContentModel.TYPE_CONTENT)
|
||||||
|
.getNodeRef();
|
||||||
recordService.createRecord(filePlan, record);
|
recordService.createRecord(filePlan, record);
|
||||||
return record;
|
return record;
|
||||||
}
|
}
|
||||||
@@ -279,4 +289,238 @@ public class ExtendedSecurityServiceImplTest extends BaseRMTestCase
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testConcurrentSetWithRetry()
|
||||||
|
{
|
||||||
|
Set<String> extendedReaders = new HashSet<>(2);
|
||||||
|
Set<String> extendedWriters = new HashSet<>(2);
|
||||||
|
|
||||||
|
Set<NodeRef> documents = setupConcurrentTestCase(10, extendedReaders, extendedWriters);
|
||||||
|
|
||||||
|
// For each record created previously, spawn a thread to set extended security so we cause concurrency
|
||||||
|
// failure trying to create IPR groups with the same name
|
||||||
|
fireParallelExecutionOfSetExtendedSecurity(documents, extendedReaders, extendedWriters, true);
|
||||||
|
|
||||||
|
// Look for duplicated IPR groups and verify all documents have the same groups assigned
|
||||||
|
verifyCreatedGroups(documents, false);
|
||||||
|
|
||||||
|
AuthenticationUtil.clearCurrentSecurityContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testConcurrentSetWithoutRetry()
|
||||||
|
{
|
||||||
|
Set<String> extendedReaders = new HashSet<>(2);
|
||||||
|
Set<String> extendedWriters = new HashSet<>(2);
|
||||||
|
|
||||||
|
Set<NodeRef> documents = setupConcurrentTestCase(10, extendedReaders, extendedWriters);
|
||||||
|
|
||||||
|
// For each record created previously, spawn a thread to set extended security so we cause concurrency
|
||||||
|
// failure trying to create IPR groups with the same name.
|
||||||
|
// Since there is no retry, we expect to get a ConcurrencyFailureException
|
||||||
|
Assert.assertThrows(ConcurrencyFailureException.class, () -> {
|
||||||
|
fireParallelExecutionOfSetExtendedSecurity(documents, extendedReaders, extendedWriters, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Look for duplicated IPR groups and verify all documents have the same groups assigned
|
||||||
|
// Since there was a ConcurrencyFailureException some threads failed to set extended security so some
|
||||||
|
// documents may not have IPR groups created.
|
||||||
|
verifyCreatedGroups(documents, true);
|
||||||
|
|
||||||
|
AuthenticationUtil.clearCurrentSecurityContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<NodeRef> setupConcurrentTestCase(int concurrentThreads, Set<String> extendedReaders, Set<String> extendedWriters)
|
||||||
|
{
|
||||||
|
final String usera = createTestUser();
|
||||||
|
final String userb = createTestUser();
|
||||||
|
final String owner = createTestUser();
|
||||||
|
|
||||||
|
extendedReaders.add(usera);
|
||||||
|
extendedReaders.add(userb);
|
||||||
|
extendedWriters.add(usera);
|
||||||
|
extendedWriters.add(userb);
|
||||||
|
|
||||||
|
AuthenticationUtil.setAdminUserAsFullyAuthenticatedUser();
|
||||||
|
|
||||||
|
// Create a site
|
||||||
|
NodeRef documentLib = createSite(new HashSet<>(), new HashSet<>());
|
||||||
|
|
||||||
|
// Create records in the site document library
|
||||||
|
return createRecords(concurrentThreads, documentLib, owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
private NodeRef createSite(Set<String> readers, Set<String> writers)
|
||||||
|
{
|
||||||
|
return retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>() {
|
||||||
|
@Override
|
||||||
|
public NodeRef execute() throws Throwable
|
||||||
|
{
|
||||||
|
final String siteShortName = GUID.generate();
|
||||||
|
siteService.createSite(null, siteShortName, "test", "test", SiteVisibility.PRIVATE);
|
||||||
|
readers.forEach(reader -> siteService.setMembership(siteShortName, reader, SiteModel.SITE_CONSUMER));
|
||||||
|
writers.forEach(writer -> siteService.setMembership(siteShortName, writer, SiteModel.SITE_COLLABORATOR));
|
||||||
|
return siteService.createContainer(siteShortName, SiteService.DOCUMENT_LIBRARY, null, null);
|
||||||
|
}
|
||||||
|
}, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<NodeRef> createRecords(int numRecords, NodeRef parent, String owner)
|
||||||
|
{
|
||||||
|
return retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Set<NodeRef>>() {
|
||||||
|
@Override
|
||||||
|
public Set<NodeRef> execute() throws Throwable
|
||||||
|
{
|
||||||
|
int createdRecords = 0;
|
||||||
|
Set<NodeRef> documents = new HashSet<>();
|
||||||
|
while (createdRecords < numRecords)
|
||||||
|
{
|
||||||
|
final NodeRef doc = fileFolderService.create(parent, GUID.generate(), ContentModel.TYPE_CONTENT).getNodeRef();
|
||||||
|
ownableService.setOwner(doc, owner);
|
||||||
|
recordService.createRecord(filePlan, doc, rmFolder, true);
|
||||||
|
recordService.file(doc);
|
||||||
|
recordService.complete(doc);
|
||||||
|
documents.add(doc);
|
||||||
|
createdRecords++;
|
||||||
|
}
|
||||||
|
return documents;
|
||||||
|
}
|
||||||
|
}, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setExtendedSecurity(NodeRef doc, Set<String> readers, Set<String> writers, boolean useRetry)
|
||||||
|
{
|
||||||
|
if (!useRetry)
|
||||||
|
{
|
||||||
|
setExtendedSecurity(doc, readers, writers);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
|
||||||
|
@Override
|
||||||
|
public Void execute() throws Throwable
|
||||||
|
{
|
||||||
|
setExtendedSecurity(doc, readers, writers);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setExtendedSecurity(NodeRef doc, Set<String> readers, Set<String> writers)
|
||||||
|
{
|
||||||
|
AuthenticationUtil.setAdminUserAsFullyAuthenticatedUser();
|
||||||
|
extendedSecurityService.set(doc, readers, writers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fireParallelExecutionOfSetExtendedSecurity(Set<NodeRef> documents, Set<String> extendedReaders, Set<String> extendedWriters, boolean useRetry)
|
||||||
|
{
|
||||||
|
CompletableFuture<?>[] futures = documents.stream()
|
||||||
|
.map(doc -> CompletableFuture.runAsync(() -> setExtendedSecurity(doc, extendedReaders, extendedWriters, useRetry)))
|
||||||
|
.toArray(CompletableFuture[]::new);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CompletableFuture.allOf(futures).join();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Throwable cause = e.getCause();
|
||||||
|
if (cause instanceof ConcurrencyFailureException)
|
||||||
|
{
|
||||||
|
throw (ConcurrencyFailureException) cause;
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Error during parallel execution", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyCreatedGroups(Set<NodeRef> documents, boolean onlyDuplicatesValidation)
|
||||||
|
{
|
||||||
|
retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
|
||||||
|
@Override
|
||||||
|
public Void execute() throws Throwable
|
||||||
|
{
|
||||||
|
Set<String> expectedAuthorities = null;
|
||||||
|
Set<Set<String>> errors = new HashSet<>();
|
||||||
|
for (NodeRef doc : documents)
|
||||||
|
{
|
||||||
|
Set<AccessPermission> permissions = permissionService.getAllSetPermissions(doc);
|
||||||
|
Set<String> authorities = getDocumentAuthorities(permissions);
|
||||||
|
Set<String> authoritiesById = getAuthorityIds(authorities);
|
||||||
|
|
||||||
|
verifyIPRGroups(authorities, onlyDuplicatesValidation);
|
||||||
|
|
||||||
|
if (onlyDuplicatesValidation)
|
||||||
|
{
|
||||||
|
// Some documents may not have IPR groups created if there was a ConcurrencyFailureException
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All documents should have the same exact set of groups assigned
|
||||||
|
if (expectedAuthorities == null)
|
||||||
|
{
|
||||||
|
expectedAuthorities = authoritiesById;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!expectedAuthorities.equals(authoritiesById))
|
||||||
|
{
|
||||||
|
errors.add(authoritiesById);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue("Unexpected authorities linked to document", errors.isEmpty());
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> getDocumentAuthorities(Set<AccessPermission> permissions)
|
||||||
|
{
|
||||||
|
Set<String> authorities = new HashSet<>();
|
||||||
|
|
||||||
|
for (AccessPermission accessPermission : permissions)
|
||||||
|
{
|
||||||
|
String authority = accessPermission.getAuthority();
|
||||||
|
String authName = authorityService.getName(AuthorityType.GROUP, authority);
|
||||||
|
authorities.add(authName);
|
||||||
|
|
||||||
|
}
|
||||||
|
return authorities;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> getAuthorityIds(Set<String> authorities)
|
||||||
|
{
|
||||||
|
Set<String> authorityIds = new HashSet<>();
|
||||||
|
for (String authority : authorities)
|
||||||
|
{
|
||||||
|
String authId = authorityService.getAuthorityNodeRef(authority) != null
|
||||||
|
? authorityService.getAuthorityNodeRef(authority).getId()
|
||||||
|
: null;
|
||||||
|
authorityIds.add(authId);
|
||||||
|
}
|
||||||
|
return authorityIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyIPRGroups(Set<String> authorities, boolean onlyDuplicatesValidation)
|
||||||
|
{
|
||||||
|
boolean hasGroupIPR = false;
|
||||||
|
|
||||||
|
for (String authorityName : authorities)
|
||||||
|
{
|
||||||
|
String shortName = authorityService.getShortName(authorityName);
|
||||||
|
|
||||||
|
if (authorityName.startsWith("GROUP_IPR"))
|
||||||
|
{
|
||||||
|
hasGroupIPR = true;
|
||||||
|
PagingResults<String> results = authorityService.getAuthorities(AuthorityType.GROUP, null, shortName, false,
|
||||||
|
false, new PagingRequest(0, 10));
|
||||||
|
|
||||||
|
assertEquals("No duplicated IPR group expected", 1, results.getPage().size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!onlyDuplicatesValidation)
|
||||||
|
{
|
||||||
|
assertTrue("No IPR Groups created", hasGroupIPR);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
@@ -51,8 +51,8 @@
|
|||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-lang</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@ import java.util.ResourceBundle;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringEscapeUtils;
|
import org.apache.commons.lang3.StringEscapeUtils;
|
||||||
import org.json.simple.JSONObject;
|
import org.json.simple.JSONObject;
|
||||||
import org.springframework.extensions.webscripts.Cache;
|
import org.springframework.extensions.webscripts.Cache;
|
||||||
import org.springframework.extensions.webscripts.Status;
|
import org.springframework.extensions.webscripts.Status;
|
||||||
@@ -92,7 +92,7 @@ public class WikiPageGet extends AbstractWikiWebScript
|
|||||||
{
|
{
|
||||||
links.add(link);
|
links.add(link);
|
||||||
// build the list of available pages
|
// build the list of available pages
|
||||||
WikiPageInfo wikiPage = wikiService.getWikiPage(site.getShortName(), StringEscapeUtils.unescapeHtml(link));
|
WikiPageInfo wikiPage = wikiService.getWikiPage(site.getShortName(), StringEscapeUtils.unescapeHtml4(link));
|
||||||
if (wikiPage != null)
|
if (wikiPage != null)
|
||||||
{
|
{
|
||||||
pageTitles.add(wikiPage.getTitle());
|
pageTitles.add(wikiPage.getTitle());
|
||||||
|
@@ -91,6 +91,15 @@ function doclist_getAllNodes(parsedArgs, filterParams, query, totalItemCount)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sanitizeJunkFavouriteKeys(favourites){
|
||||||
|
for (var key in favourites) {
|
||||||
|
if (!key || key.trim() === "") {
|
||||||
|
delete favourites[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return favourites;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main entry point: Create collection of documents and folders in the given space
|
* Main entry point: Create collection of documents and folders in the given space
|
||||||
*
|
*
|
||||||
@@ -123,6 +132,47 @@ function doclist_main()
|
|||||||
|
|
||||||
if (logger.isLoggingEnabled())
|
if (logger.isLoggingEnabled())
|
||||||
logger.log("doclist.lib.js - NodeRef: " + parsedArgs.nodeRef + " Query: " + query);
|
logger.log("doclist.lib.js - NodeRef: " + parsedArgs.nodeRef + " Query: " + query);
|
||||||
|
|
||||||
|
favourites = sanitizeJunkFavouriteKeys(favourites);
|
||||||
|
if(query === null)
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
luceneQuery: "",
|
||||||
|
paging: {
|
||||||
|
totalRecords: 0,
|
||||||
|
startIndex: 0
|
||||||
|
},
|
||||||
|
container: parsedArgs.rootNode,
|
||||||
|
parent: null,
|
||||||
|
onlineEditing: utils.moduleInstalled("org.alfresco.module.vti"),
|
||||||
|
itemCount: {
|
||||||
|
folders: 0,
|
||||||
|
documents: 0
|
||||||
|
},
|
||||||
|
items: [],
|
||||||
|
customJSON: slingshotDocLib.getJSON()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Object.keys(favourites).length === 0 && query === null)
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
luceneQuery: "",
|
||||||
|
paging: {
|
||||||
|
totalRecords: 0,
|
||||||
|
startIndex: 0
|
||||||
|
},
|
||||||
|
container: parsedArgs.rootNode,
|
||||||
|
parent: null,
|
||||||
|
onlineEditing: utils.moduleInstalled("org.alfresco.module.vti"),
|
||||||
|
itemCount: {
|
||||||
|
folders: 0,
|
||||||
|
documents: 0
|
||||||
|
},
|
||||||
|
items: [],
|
||||||
|
customJSON: slingshotDocLib.getJSON()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
var totalItemCount = filterParams.limitResults ? parseInt(filterParams.limitResults, 10) : -1;
|
var totalItemCount = filterParams.limitResults ? parseInt(filterParams.limitResults, 10) : -1;
|
||||||
// For all sites documentLibrary query we pull in all available results and post filter
|
// For all sites documentLibrary query we pull in all available results and post filter
|
||||||
|
@@ -182,11 +182,14 @@ var Filters =
|
|||||||
case "favourites":
|
case "favourites":
|
||||||
for (var favourite in favourites)
|
for (var favourite in favourites)
|
||||||
{
|
{
|
||||||
if (filterQuery)
|
if (favourite && favourite.trim() !== "")
|
||||||
{
|
{
|
||||||
filterQuery += " OR ";
|
if (filterQuery)
|
||||||
|
{
|
||||||
|
filterQuery += " OR ";
|
||||||
|
}
|
||||||
|
filterQuery += "ID:\"" + favourite + "\"";
|
||||||
}
|
}
|
||||||
filterQuery += "ID:\"" + favourite + "\"";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filterQuery.length !== 0)
|
if (filterQuery.length !== 0)
|
||||||
@@ -201,7 +204,13 @@ var Filters =
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// empty favourites query
|
// empty favourites query
|
||||||
filterQuery = "+ID:\"\"";
|
logger.warn("No favourites found for user: " + person.properties.userName);
|
||||||
|
return {
|
||||||
|
query: null,
|
||||||
|
limitResults: 0,
|
||||||
|
sort: [],
|
||||||
|
language: "lucene"
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
filterParams.query = filterQuery;
|
filterParams.query = filterQuery;
|
||||||
@@ -224,15 +233,15 @@ var Filters =
|
|||||||
filterParams.query = "+ID:\"" + parsedArgs.nodeRef + "\"";
|
filterParams.query = "+ID:\"" + parsedArgs.nodeRef + "\"";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "tag":
|
case "tag":
|
||||||
// Remove any trailing "/" character
|
// Remove any trailing "/" character
|
||||||
if (filterData.charAt(filterData.length - 1) == "/")
|
if (filterData.charAt(filterData.length - 1) == "/")
|
||||||
{
|
{
|
||||||
filterData = filterData.slice(0, -1);
|
filterData = filterData.slice(0, -1);
|
||||||
}
|
}
|
||||||
filterQuery = this.constructPathQuery(parsedArgs);
|
filterQuery = this.constructPathQuery(parsedArgs);
|
||||||
filterParams.query = filterQuery + " +PATH:\"/cm:taggable/cm:" + search.ISO9075Encode(filterData) + "/member\"";
|
filterParams.query = filterQuery + " +TAG:\"" + search.ISO9075Encode(filterData) + "\"";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "category":
|
case "category":
|
||||||
// Remove any trailing "/" character
|
// Remove any trailing "/" character
|
||||||
@@ -240,8 +249,15 @@ var Filters =
|
|||||||
{
|
{
|
||||||
filterData = filterData.slice(0, -1);
|
filterData = filterData.slice(0, -1);
|
||||||
}
|
}
|
||||||
filterQuery = this.constructPathQuery(parsedArgs);
|
|
||||||
filterParams.query = filterQuery + " +PATH:\"/cm:categoryRoot/cm:generalclassifiable" + Filters.iso9075EncodePath(filterData) + "/member\"";
|
var categoryNodeRef = this.getCategoryNodeRef(filterData);
|
||||||
|
|
||||||
|
if (categoryNodeRef && search.findNode(categoryNodeRef) != null) {
|
||||||
|
filterParams.query = filterQuery + ' +@cm\\:categories:"' + categoryNodeRef + '"';
|
||||||
|
} else {
|
||||||
|
logger.warn("category filter: skipping invalid category node : " + categoryNodeRef);
|
||||||
|
}
|
||||||
|
filterParams.language = "fts-alfresco";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "aspect":
|
case "aspect":
|
||||||
@@ -262,11 +278,24 @@ var Filters =
|
|||||||
{
|
{
|
||||||
filterParams.query += " " + (Filters.TYPE_MAP[parsedArgs.type] || "");
|
filterParams.query += " " + (Filters.TYPE_MAP[parsedArgs.type] || "");
|
||||||
}
|
}
|
||||||
|
logger.warn("Final Query : " + filterParams.query);
|
||||||
return filterParams;
|
return filterParams;
|
||||||
},
|
},
|
||||||
|
|
||||||
constructPathQuery: function constructPathQuery(parsedArgs)
|
getCategoryNodeRef: function(categoryName) {
|
||||||
|
var results = search.luceneSearch(
|
||||||
|
'PATH:"/cm:categoryRoot/cm:generalclassifiable//*" AND @cm\\:name:"' + categoryName + '"'
|
||||||
|
);
|
||||||
|
|
||||||
|
if (results && results.length > 0) {
|
||||||
|
return results[0].nodeRef.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.warn("Category not found: " + categoryName);
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
constructPathQuery: function(parsedArgs)
|
||||||
{
|
{
|
||||||
var pathQuery = "";
|
var pathQuery = "";
|
||||||
if (parsedArgs.libraryRoot != companyhome || parsedArgs.nodeRef != "alfresco://company/home")
|
if (parsedArgs.libraryRoot != companyhome || parsedArgs.nodeRef != "alfresco://company/home")
|
||||||
|
@@ -25,7 +25,7 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import jakarta.transaction.UserTransaction;
|
import jakarta.transaction.UserTransaction;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringEscapeUtils;
|
import org.apache.commons.lang3.StringEscapeUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
@@ -958,7 +958,7 @@ public class WikiRestApiTest extends BaseWebScriptTest
|
|||||||
String link = m.group(1);
|
String link = m.group(1);
|
||||||
link += "?title=<script>alert('xss');</script>";
|
link += "?title=<script>alert('xss');</script>";
|
||||||
WikiPageInfo wikiPage2 = this.wikiService.getWikiPage(SITE_SHORT_NAME_WIKI, link);
|
WikiPageInfo wikiPage2 = this.wikiService.getWikiPage(SITE_SHORT_NAME_WIKI, link);
|
||||||
WikiPageInfo wikiPage1 = this.wikiService.getWikiPage(SITE_SHORT_NAME_WIKI, StringEscapeUtils.unescapeHtml(link));
|
WikiPageInfo wikiPage1 = this.wikiService.getWikiPage(SITE_SHORT_NAME_WIKI, StringEscapeUtils.unescapeHtml4(link));
|
||||||
assertEquals(wikiPage2, wikiPage1);
|
assertEquals(wikiPage2, wikiPage1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@@ -9,6 +9,6 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
</project>
|
</project>
|
||||||
|
@@ -37,8 +37,7 @@ commons-fileupload http://jakarta.apache.org/commons/
|
|||||||
commons-httpclient http://jakarta.apache.org/commons/
|
commons-httpclient http://jakarta.apache.org/commons/
|
||||||
commons-io http://jakarta.apache.org/commons/
|
commons-io http://jakarta.apache.org/commons/
|
||||||
commons-jxpath http://jakarta.apache.org/commons/
|
commons-jxpath http://jakarta.apache.org/commons/
|
||||||
commons-lang http://jakarta.apache.org/commons/
|
commons-lang3 http://jakarta.apache.org/commons/
|
||||||
commons-lang3 http://jakarta.apache.org/commons/
|
|
||||||
commons-logging http://jakarta.apache.org/commons/
|
commons-logging http://jakarta.apache.org/commons/
|
||||||
commons-net http://jakarta.apache.org/commons/
|
commons-net http://jakarta.apache.org/commons/
|
||||||
commons-pool http://jakarta.apache.org/commons/
|
commons-pool http://jakarta.apache.org/commons/
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<organization>
|
<organization>
|
||||||
|
@@ -5,7 +5,7 @@ import java.util.Date;
|
|||||||
import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
|
import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
|
||||||
import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
|
import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
|
||||||
import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
|
import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
|
||||||
import org.apache.commons.lang.time.DateUtils;
|
import org.apache.commons.lang3.time.DateUtils;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<developers>
|
<developers>
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<developers>
|
<developers>
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<developers>
|
<developers>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
32
pom.xml
32
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">
|
<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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<name>Alfresco Community Repo Parent</name>
|
<name>Alfresco Community Repo Parent</name>
|
||||||
|
|
||||||
@@ -51,10 +51,10 @@
|
|||||||
<dependency.alfresco-server-root.version>7.0.2</dependency.alfresco-server-root.version>
|
<dependency.alfresco-server-root.version>7.0.2</dependency.alfresco-server-root.version>
|
||||||
<dependency.activiti-engine.version>5.23.0</dependency.activiti-engine.version>
|
<dependency.activiti-engine.version>5.23.0</dependency.activiti-engine.version>
|
||||||
<dependency.activiti.version>5.23.0</dependency.activiti.version>
|
<dependency.activiti.version>5.23.0</dependency.activiti.version>
|
||||||
<dependency.alfresco-transform-core.version>5.2.1-A.3</dependency.alfresco-transform-core.version>
|
<dependency.alfresco-transform-core.version>5.2.2-A.1</dependency.alfresco-transform-core.version>
|
||||||
<dependency.alfresco-transform-service.version>4.2.1-A.4</dependency.alfresco-transform-service.version>
|
<dependency.alfresco-transform-service.version>4.2.2-A.1</dependency.alfresco-transform-service.version>
|
||||||
<dependency.alfresco-greenmail.version>7.1</dependency.alfresco-greenmail.version>
|
<dependency.alfresco-greenmail.version>7.1</dependency.alfresco-greenmail.version>
|
||||||
<dependency.acs-event-model.version>1.0.5</dependency.acs-event-model.version>
|
<dependency.acs-event-model.version>1.0.9</dependency.acs-event-model.version>
|
||||||
|
|
||||||
<dependency.aspectj.version>1.9.22.1</dependency.aspectj.version>
|
<dependency.aspectj.version>1.9.22.1</dependency.aspectj.version>
|
||||||
<dependency.spring.version>6.2.8</dependency.spring.version>
|
<dependency.spring.version>6.2.8</dependency.spring.version>
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
<dependency.slf4j.version>2.0.16</dependency.slf4j.version>
|
<dependency.slf4j.version>2.0.16</dependency.slf4j.version>
|
||||||
<dependency.log4j.version>2.25.1</dependency.log4j.version>
|
<dependency.log4j.version>2.25.1</dependency.log4j.version>
|
||||||
<dependency.groovy.version>3.0.25</dependency.groovy.version>
|
<dependency.groovy.version>3.0.25</dependency.groovy.version>
|
||||||
<dependency.tika.version>2.9.2</dependency.tika.version>
|
<dependency.tika.version>3.2.3</dependency.tika.version>
|
||||||
<dependency.truezip.version>7.7.10</dependency.truezip.version>
|
<dependency.truezip.version>7.7.10</dependency.truezip.version>
|
||||||
<dependency.poi.version>5.4.0</dependency.poi.version>
|
<dependency.poi.version>5.4.0</dependency.poi.version>
|
||||||
<dependency.jboss.logging.version>3.5.0.Final</dependency.jboss.logging.version>
|
<dependency.jboss.logging.version>3.5.0.Final</dependency.jboss.logging.version>
|
||||||
@@ -154,7 +154,7 @@
|
|||||||
<connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
|
<connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
|
||||||
<developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
|
<developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
|
||||||
<url>https://github.com/Alfresco/alfresco-community-repo</url>
|
<url>https://github.com/Alfresco/alfresco-community-repo</url>
|
||||||
<tag>HEAD</tag>
|
<tag>25.3.0.42</tag>
|
||||||
</scm>
|
</scm>
|
||||||
|
|
||||||
<distributionManagement>
|
<distributionManagement>
|
||||||
@@ -170,6 +170,12 @@
|
|||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<!-- v1.10 has 0BSD license it must be consulted with Legal -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.tukaani</groupId>
|
||||||
|
<artifactId>xz</artifactId>
|
||||||
|
<version>1.9</version>
|
||||||
|
</dependency>
|
||||||
<!-- Jakarta... -->
|
<!-- Jakarta... -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>jakarta.xml.bind</groupId>
|
<groupId>jakarta.xml.bind</groupId>
|
||||||
@@ -422,9 +428,9 @@
|
|||||||
<version>1.18.0</version>
|
<version>1.18.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-lang</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>2.6</version>
|
<version>3.18.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
@@ -1125,16 +1131,10 @@
|
|||||||
<exclude>jakarta.xml.soap:jakarta.xml.soap-api:(, 2.0.1)</exclude>
|
<exclude>jakarta.xml.soap:jakarta.xml.soap-api:(, 2.0.1)</exclude>
|
||||||
<exclude>jakarta.jws:jakarta.jws-api:(, 3.0.0)</exclude>
|
<exclude>jakarta.jws:jakarta.jws-api:(, 3.0.0)</exclude>
|
||||||
<!-- Enforce ban bouncycastle dependencies other than specified under <includes> section-->
|
<!-- Enforce ban bouncycastle dependencies other than specified under <includes> section-->
|
||||||
<exclude>org.bouncycastle</exclude>
|
<exclude>org.bouncycastle:(,1.81)</exclude>
|
||||||
<!-- Enforce one version of Jaxb-->
|
<!-- Enforce one version of Jaxb-->
|
||||||
<exclude>com.sun.xml.bind</exclude>
|
<exclude>com.sun.xml.bind</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
<includes>
|
|
||||||
<include>org.bouncycastle:bcprov-jdk18on:[1.78.1,)</include>
|
|
||||||
<include>org.bouncycastle:bcmail-jdk18on:[1.78.1,)</include>
|
|
||||||
<include>org.bouncycastle:bcpkix-jdk18on:[1.78.1,)</include>
|
|
||||||
<include>org.bouncycastle:bcutil-jdk18on:[1.78.1,)</include>
|
|
||||||
</includes>
|
|
||||||
</bannedDependencies>
|
</bannedDependencies>
|
||||||
</rules>
|
</rules>
|
||||||
<fail>true</fail>
|
<fail>true</fail>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@@ -40,6 +40,7 @@
|
|||||||
"items":
|
"items":
|
||||||
[
|
[
|
||||||
<#list results as row>
|
<#list results as row>
|
||||||
|
<#if row.item.hasPermission("Read")>
|
||||||
{
|
{
|
||||||
"type": "${row.item.typeShort}",
|
"type": "${row.item.typeShort}",
|
||||||
"parentType": "${row.item.parentTypeShort!""}",
|
"parentType": "${row.item.parentTypeShort!""}",
|
||||||
@@ -75,6 +76,7 @@
|
|||||||
"nodeRef": "${row.item.nodeRef}"<#if row.selectable?exists>,
|
"nodeRef": "${row.item.nodeRef}"<#if row.selectable?exists>,
|
||||||
"selectable" : ${row.selectable?string}</#if>
|
"selectable" : ${row.selectable?string}</#if>
|
||||||
}<#if row_has_next>,</#if>
|
}<#if row_has_next>,</#if>
|
||||||
|
</#if>
|
||||||
</#list>
|
</#list>
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>25.3.0.25-SNAPSHOT</version>
|
<version>25.3.0.42</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@@ -94,7 +94,6 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>3.18.0</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-codec</groupId>
|
<groupId>commons-codec</groupId>
|
||||||
@@ -737,10 +736,6 @@
|
|||||||
<artifactId>reflections</artifactId>
|
<artifactId>reflections</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>commons-lang</groupId>
|
|
||||||
<artifactId>commons-lang</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@@ -70,6 +70,13 @@ public interface AuditComponent
|
|||||||
*/
|
*/
|
||||||
public void setUserAuditFilter(UserAuditFilter userAuditFilter);
|
public void setUserAuditFilter(UserAuditFilter userAuditFilter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param auditRecordReporter
|
||||||
|
* AuditRecordReporter
|
||||||
|
* @since 25.3
|
||||||
|
*/
|
||||||
|
public void setAuditRecordReporter(AuditRecordReporter auditRecordReporter);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all registered audit applications, whether active or not.
|
* Get all registered audit applications, whether active or not.
|
||||||
*
|
*
|
||||||
|
@@ -48,7 +48,6 @@ import org.alfresco.repo.audit.model.AuditModelRegistryImpl;
|
|||||||
import org.alfresco.repo.domain.audit.AuditDAO;
|
import org.alfresco.repo.domain.audit.AuditDAO;
|
||||||
import org.alfresco.repo.domain.propval.PropertyValueDAO;
|
import org.alfresco.repo.domain.propval.PropertyValueDAO;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
|
||||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
|
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||||
@@ -73,8 +72,8 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
{
|
{
|
||||||
private static final String INBOUND_LOGGER = "org.alfresco.repo.audit.inbound";
|
private static final String INBOUND_LOGGER = "org.alfresco.repo.audit.inbound";
|
||||||
|
|
||||||
private static Log logger = LogFactory.getLog(AuditComponentImpl.class);
|
private static final Log logger = LogFactory.getLog(AuditComponentImpl.class);
|
||||||
private static Log loggerInbound = LogFactory.getLog(INBOUND_LOGGER);
|
private static final Log loggerInbound = LogFactory.getLog(INBOUND_LOGGER);
|
||||||
|
|
||||||
private AuditModelRegistryImpl auditModelRegistry;
|
private AuditModelRegistryImpl auditModelRegistry;
|
||||||
private PropertyValueDAO propertyValueDAO;
|
private PropertyValueDAO propertyValueDAO;
|
||||||
@@ -82,6 +81,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
private TransactionService transactionService;
|
private TransactionService transactionService;
|
||||||
private AuditFilter auditFilter;
|
private AuditFilter auditFilter;
|
||||||
private UserAuditFilter userAuditFilter;
|
private UserAuditFilter userAuditFilter;
|
||||||
|
private AuditRecordReporter auditRecordReporter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor
|
* Default constructor
|
||||||
@@ -140,6 +140,11 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
this.userAuditFilter = userAuditFilter;
|
this.userAuditFilter = userAuditFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAuditRecordReporter(AuditRecordReporter auditRecordReporter)
|
||||||
|
{
|
||||||
|
this.auditRecordReporter = auditRecordReporter;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*
|
*
|
||||||
@@ -215,7 +220,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
public int deleteAuditEntries(List<Long> auditEntryIds)
|
public int deleteAuditEntries(List<Long> auditEntryIds)
|
||||||
{
|
{
|
||||||
// Shortcut, if necessary
|
// Shortcut, if necessary
|
||||||
if (auditEntryIds.size() == 0)
|
if (auditEntryIds.isEmpty())
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -234,7 +239,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
{
|
{
|
||||||
Long disabledPathsId = application.getDisabledPathsId();
|
Long disabledPathsId = application.getDisabledPathsId();
|
||||||
Set<String> disabledPaths = (Set<String>) propertyValueDAO.getPropertyById(disabledPathsId);
|
Set<String> disabledPaths = (Set<String>) propertyValueDAO.getPropertyById(disabledPathsId);
|
||||||
return new HashSet<String>(disabledPaths);
|
return new HashSet<>(disabledPaths);
|
||||||
}
|
}
|
||||||
catch (Throwable e)
|
catch (Throwable e)
|
||||||
{
|
{
|
||||||
@@ -254,6 +259,16 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
return auditModelRegistry.isAuditEnabled();
|
return auditModelRegistry.isAuditEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAuditingToDatabaseEnabled()
|
||||||
|
{
|
||||||
|
return auditModelRegistry.isAuditingToDatabaseEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAuditingToAuditStorageEnabled()
|
||||||
|
{
|
||||||
|
return auditModelRegistry.isAuditingToAuditStorageEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*
|
*
|
||||||
@@ -309,7 +324,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
{
|
{
|
||||||
PathMapper pathMapper = auditModelRegistry.getAuditPathMapper();
|
PathMapper pathMapper = auditModelRegistry.getAuditPathMapper();
|
||||||
Set<String> mappedPaths = pathMapper.getMappedPathsWithPartialMatch(path);
|
Set<String> mappedPaths = pathMapper.getMappedPathsWithPartialMatch(path);
|
||||||
return loggerInbound.isDebugEnabled() || mappedPaths.size() > 0;
|
return loggerInbound.isDebugEnabled() || !mappedPaths.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -346,7 +361,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
|
|
||||||
// Check if there are any entries that match or supercede the given path
|
// Check if there are any entries that match or supercede the given path
|
||||||
String disablingPath = null;
|
String disablingPath = null;
|
||||||
;
|
|
||||||
for (String disabledPath : disabledPaths)
|
for (String disabledPath : disabledPaths)
|
||||||
{
|
{
|
||||||
if (path.startsWith(disabledPath))
|
if (path.startsWith(disabledPath))
|
||||||
@@ -573,7 +588,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build the key paths using the session root path
|
// Build the key paths using the session root path
|
||||||
Map<String, Serializable> pathedValues = new HashMap<String, Serializable>(values.size() * 2);
|
Map<String, Serializable> pathedValues = new HashMap<>(values.size() * 2);
|
||||||
for (Map.Entry<String, Serializable> entry : values.entrySet())
|
for (Map.Entry<String, Serializable> entry : values.entrySet())
|
||||||
{
|
{
|
||||||
String pathElement = entry.getKey();
|
String pathElement = entry.getKey();
|
||||||
@@ -596,12 +611,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
case TXN_NONE:
|
case TXN_NONE:
|
||||||
case TXN_READ_ONLY:
|
case TXN_READ_ONLY:
|
||||||
// New transaction
|
// New transaction
|
||||||
RetryingTransactionCallback<Map<String, Serializable>> callback = new RetryingTransactionCallback<Map<String, Serializable>>() {
|
RetryingTransactionCallback<Map<String, Serializable>> callback = () -> recordAuditValuesImpl(mappedValues);
|
||||||
public Map<String, Serializable> execute() throws Throwable
|
|
||||||
{
|
|
||||||
return recordAuditValuesImpl(mappedValues);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
RetryingTransactionHelper txnHelper = transactionService.getRetryingTransactionHelper();
|
RetryingTransactionHelper txnHelper = transactionService.getRetryingTransactionHelper();
|
||||||
txnHelper.setForceWritable(true);
|
txnHelper.setForceWritable(true);
|
||||||
return txnHelper.doInTransaction(callback, false, true);
|
return txnHelper.doInTransaction(callback, false, true);
|
||||||
@@ -618,21 +628,16 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
public Map<String, Serializable> recordAuditValuesImpl(Map<String, Serializable> mappedValues)
|
public Map<String, Serializable> recordAuditValuesImpl(Map<String, Serializable> mappedValues)
|
||||||
{
|
{
|
||||||
// Group the values by root path
|
// Group the values by root path
|
||||||
Map<String, Map<String, Serializable>> mappedValuesByRootKey = new HashMap<String, Map<String, Serializable>>();
|
Map<String, Map<String, Serializable>> mappedValuesByRootKey = new HashMap<>();
|
||||||
for (Map.Entry<String, Serializable> entry : mappedValues.entrySet())
|
for (Map.Entry<String, Serializable> entry : mappedValues.entrySet())
|
||||||
{
|
{
|
||||||
String path = entry.getKey();
|
String path = entry.getKey();
|
||||||
String rootKey = AuditApplication.getRootKey(path);
|
String rootKey = AuditApplication.getRootKey(path);
|
||||||
Map<String, Serializable> rootKeyMappedValues = mappedValuesByRootKey.get(rootKey);
|
Map<String, Serializable> rootKeyMappedValues = mappedValuesByRootKey.computeIfAbsent(rootKey, k -> new HashMap<>(7));
|
||||||
if (rootKeyMappedValues == null)
|
|
||||||
{
|
|
||||||
rootKeyMappedValues = new HashMap<String, Serializable>(7);
|
|
||||||
mappedValuesByRootKey.put(rootKey, rootKeyMappedValues);
|
|
||||||
}
|
|
||||||
rootKeyMappedValues.put(path, entry.getValue());
|
rootKeyMappedValues.put(path, entry.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Serializable> allAuditedValues = new HashMap<String, Serializable>(mappedValues.size() * 2 + 1);
|
Map<String, Serializable> allAuditedValues = new HashMap<>(mappedValues.size() * 2 + 1);
|
||||||
// Now audit for each of the root keys
|
// Now audit for each of the root keys
|
||||||
for (Map.Entry<String, Map<String, Serializable>> entry : mappedValuesByRootKey.entrySet())
|
for (Map.Entry<String, Map<String, Serializable>> entry : mappedValuesByRootKey.entrySet())
|
||||||
{
|
{
|
||||||
@@ -694,7 +699,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if there is anything to audit
|
// Check if there is anything to audit
|
||||||
if (values.size() == 0)
|
if (values.isEmpty())
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
@@ -727,12 +732,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
Map<String, Serializable> auditData = generateData(generators);
|
Map<String, Serializable> auditData = generateData(generators);
|
||||||
|
|
||||||
// Now extract values
|
// Now extract values
|
||||||
Map<String, Serializable> extractedData = AuthenticationUtil.runAs(new RunAsWork<Map<String, Serializable>>() {
|
Map<String, Serializable> extractedData = AuthenticationUtil.runAs(() -> extractData(application, values), AuthenticationUtil.getSystemUserName());
|
||||||
public Map<String, Serializable> doWork() throws Exception
|
|
||||||
{
|
|
||||||
return extractData(application, values);
|
|
||||||
}
|
|
||||||
}, AuthenticationUtil.getSystemUserName());
|
|
||||||
|
|
||||||
// Combine extracted and generated values (extracted data takes precedence)
|
// Combine extracted and generated values (extracted data takes precedence)
|
||||||
auditData.putAll(extractedData);
|
auditData.putAll(extractedData);
|
||||||
@@ -743,8 +743,8 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
{
|
{
|
||||||
String root = value.getKey();
|
String root = value.getKey();
|
||||||
int index = root.lastIndexOf("/");
|
int index = root.lastIndexOf("/");
|
||||||
Map<String, Serializable> argc = new HashMap<String, Serializable>(1);
|
Map<String, Serializable> argc = new HashMap<>(1);
|
||||||
argc.put(root.substring(index, root.length()).substring(1), value.getValue());
|
argc.put(root.substring(index).substring(1), value.getValue());
|
||||||
if (!auditFilter.accept(root.substring(0, index), argc))
|
if (!auditFilter.accept(root.substring(0, index), argc))
|
||||||
{
|
{
|
||||||
return Collections.emptyMap();
|
return Collections.emptyMap();
|
||||||
@@ -760,10 +760,15 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
{
|
{
|
||||||
// Persist the values (if not just gathering data in a pre call for use in a post call)
|
// Persist the values (if not just gathering data in a pre call for use in a post call)
|
||||||
boolean justGatherPreCallData = application.isApplicationJustGeneratingPreCallData();
|
boolean justGatherPreCallData = application.isApplicationJustGeneratingPreCallData();
|
||||||
if (!justGatherPreCallData)
|
if (!justGatherPreCallData && isAuditingToDatabaseEnabled())
|
||||||
{
|
{
|
||||||
entryId = auditDAO.createAuditEntry(applicationId, time, username, auditData);
|
entryId = auditDAO.createAuditEntry(applicationId, time, username, auditData);
|
||||||
}
|
}
|
||||||
|
if (isAuditingToAuditStorageEnabled())
|
||||||
|
{
|
||||||
|
auditRecordReporter.reportAuditRecord(createAuditRecord(auditData, true, username, entryId, application.getApplicationName()));
|
||||||
|
}
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
@@ -822,7 +827,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
AuditApplication application,
|
AuditApplication application,
|
||||||
Map<String, Serializable> values)
|
Map<String, Serializable> values)
|
||||||
{
|
{
|
||||||
Map<String, Serializable> newData = new HashMap<String, Serializable>(values.size());
|
Map<String, Serializable> newData = new HashMap<>(values.size());
|
||||||
|
|
||||||
List<DataExtractorDefinition> extractors = application.getDataExtractors();
|
List<DataExtractorDefinition> extractors = application.getDataExtractors();
|
||||||
for (DataExtractorDefinition extractorDef : extractors)
|
for (DataExtractorDefinition extractorDef : extractors)
|
||||||
@@ -900,7 +905,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
*/
|
*/
|
||||||
private Map<String, Serializable> generateData(Map<String, DataGenerator> generators)
|
private Map<String, Serializable> generateData(Map<String, DataGenerator> generators)
|
||||||
{
|
{
|
||||||
Map<String, Serializable> newData = new HashMap<String, Serializable>(generators.size() + 5);
|
Map<String, Serializable> newData = new HashMap<>(generators.size() + 5);
|
||||||
for (Map.Entry<String, DataGenerator> entry : generators.entrySet())
|
for (Map.Entry<String, DataGenerator> entry : generators.entrySet())
|
||||||
{
|
{
|
||||||
String path = entry.getKey();
|
String path = entry.getKey();
|
||||||
@@ -925,6 +930,20 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
return newData;
|
return newData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an AuditRecord from the provided audit data.
|
||||||
|
*/
|
||||||
|
private AuditRecord createAuditRecord(Map<String, Serializable> auditData, boolean inTransaction, String username, Long entryId, String applicationName)
|
||||||
|
{
|
||||||
|
int rootSize = applicationName.length() + 2; // Root is constructed like this -> '/' + auditedApplicationName + '/'.
|
||||||
|
AuditRecord.Builder builder = AuditRecordUtils.generateAuditRecordBuilder(auditData, rootSize);
|
||||||
|
builder.setAuditRecordType(applicationName);
|
||||||
|
builder.setInTransaction(inTransaction);
|
||||||
|
builder.setUsername(username);
|
||||||
|
builder.setEntryDBId(entryId);
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 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.audit;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class AuditRecord
|
||||||
|
{
|
||||||
|
private final boolean inTransaction;
|
||||||
|
private final String auditApplicationId;
|
||||||
|
private final ZonedDateTime createdAt;
|
||||||
|
private final String username;
|
||||||
|
private final Long entryDBId;
|
||||||
|
private final Map<String, Serializable> auditData;
|
||||||
|
|
||||||
|
public AuditRecord(Builder builder)
|
||||||
|
{
|
||||||
|
this.auditApplicationId = builder.auditRecordType;
|
||||||
|
this.inTransaction = builder.inTransaction;
|
||||||
|
this.auditData = builder.auditRecordData;
|
||||||
|
this.createdAt = ZonedDateTime.now();
|
||||||
|
this.username = builder.username;
|
||||||
|
this.entryDBId = builder.entryDBId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuditApplicationId()
|
||||||
|
{
|
||||||
|
return auditApplicationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInTransaction()
|
||||||
|
{
|
||||||
|
return inTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ZonedDateTime getCreatedAt()
|
||||||
|
{
|
||||||
|
return createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername()
|
||||||
|
{
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getEntryDBId()
|
||||||
|
{
|
||||||
|
return entryDBId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Serializable> getAuditData()
|
||||||
|
{
|
||||||
|
return auditData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder()
|
||||||
|
{
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder
|
||||||
|
{
|
||||||
|
private String auditRecordType;
|
||||||
|
private boolean inTransaction;
|
||||||
|
private Map<String, Serializable> auditRecordData;
|
||||||
|
private String username;
|
||||||
|
private Long entryDBId;
|
||||||
|
|
||||||
|
public Builder setAuditRecordType(String auditRecordType)
|
||||||
|
{
|
||||||
|
this.auditRecordType = auditRecordType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setInTransaction(boolean inTransaction)
|
||||||
|
{
|
||||||
|
this.inTransaction = inTransaction;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setAuditRecordData(Map<String, Serializable> auditRecordData)
|
||||||
|
{
|
||||||
|
this.auditRecordData = auditRecordData;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setUsername(String username)
|
||||||
|
{
|
||||||
|
this.username = username;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setEntryDBId(Long entryDBId)
|
||||||
|
{
|
||||||
|
this.entryDBId = entryDBId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuditRecord build()
|
||||||
|
{
|
||||||
|
return new AuditRecord(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 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.audit;
|
||||||
|
|
||||||
|
public interface AuditRecordReporter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* This method will report AuditRecord to Audit Storage using RepoEvent2
|
||||||
|
*
|
||||||
|
* @param auditRecord
|
||||||
|
* represent data that will be reported.
|
||||||
|
*/
|
||||||
|
void reportAuditRecord(AuditRecord auditRecord);
|
||||||
|
}
|
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 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.audit;
|
||||||
|
|
||||||
|
public class AuditRecordReporterImpl implements AuditRecordReporter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* This method intentionally has an empty implementation.
|
||||||
|
* <p>
|
||||||
|
* This class provides a no-op implementation of {@link AuditRecordReporter}.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void reportAuditRecord(AuditRecord auditRecord)
|
||||||
|
{
|
||||||
|
// No operation performed.
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 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.audit;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
|
||||||
|
public final class AuditRecordUtils
|
||||||
|
{
|
||||||
|
private AuditRecordUtils()
|
||||||
|
{
|
||||||
|
// This is a utility class and cannot be instantiated.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates an {@link AuditRecord.Builder} from flat audit data.
|
||||||
|
* <p>
|
||||||
|
* This method:
|
||||||
|
* <ul>
|
||||||
|
* <li>Translates flat {@code key-value} pairs into a nested JSON structure.</li>
|
||||||
|
* <li>Preloads the builder with the provided arguments.</li>
|
||||||
|
* <li>Splits keys by {@code /} to build the nested structure.</li>
|
||||||
|
* <li>Uses the root key as the application ID.</li>
|
||||||
|
* <li>Assumes each key starts with the same root, constructed as {@code '/' + auditedApplicationName + '/'}, which is removed before splitting.</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* a map containing flat audit data as `key-value` pairs
|
||||||
|
* @param keyRootLength
|
||||||
|
* is a length of key root.
|
||||||
|
* @return a preloaded {@link AuditRecord.Builder}
|
||||||
|
*/
|
||||||
|
public static AuditRecord.Builder generateAuditRecordBuilder(Map<String, Serializable> data, int keyRootLength)
|
||||||
|
{
|
||||||
|
var auditRecordBuilder = AuditRecord.builder();
|
||||||
|
|
||||||
|
var rootNode = createRootNode(data, keyRootLength);
|
||||||
|
|
||||||
|
auditRecordBuilder.setAuditRecordData(rootNode);
|
||||||
|
|
||||||
|
return auditRecordBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static HashMap<String, Serializable> createRootNode(Map<String, Serializable> data, int keyRootLength)
|
||||||
|
{
|
||||||
|
var rootNode = new HashMap<String, Serializable>();
|
||||||
|
|
||||||
|
data.forEach((k, v) -> {
|
||||||
|
var keys = k.substring(keyRootLength).split("/");
|
||||||
|
|
||||||
|
var current = rootNode;
|
||||||
|
for (int i = 0; i < keys.length - 1; i++)
|
||||||
|
{
|
||||||
|
current = (HashMap<String, Serializable>) current.computeIfAbsent(keys[i], newMap -> new HashMap<String, Serializable>());
|
||||||
|
}
|
||||||
|
current.put(keys[keys.length - 1], decodeValueByInstance(v));
|
||||||
|
});
|
||||||
|
return rootNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static Serializable decodeValueByInstance(Serializable value)
|
||||||
|
{
|
||||||
|
if (value instanceof HashMap<?, ?>)
|
||||||
|
{
|
||||||
|
return createRootNode((HashMap<String, Serializable>) value, 0);
|
||||||
|
}
|
||||||
|
else if (value instanceof NodeRef)
|
||||||
|
{
|
||||||
|
return ((NodeRef) value).getId();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -58,6 +58,21 @@ public interface AuditModelRegistry
|
|||||||
*/
|
*/
|
||||||
public boolean isAuditEnabled();
|
public boolean isAuditEnabled();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether audit values should be stored in database. <code>True</code> by default if not changed by property.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if audit is enabled.
|
||||||
|
*/
|
||||||
|
boolean isAuditingToDatabaseEnabled();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether audit values should be stored in audit storage.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if auditing to Audit Storage is enabled.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
boolean isAuditingToAuditStorageEnabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a map of all audit applications key by name
|
* Get a map of all audit applications key by name
|
||||||
*
|
*
|
||||||
|
@@ -85,6 +85,9 @@ public class AuditModelRegistryImpl extends AbstractPropertyBackedBean implement
|
|||||||
{
|
{
|
||||||
/** The name of the global enablement property. */
|
/** The name of the global enablement property. */
|
||||||
public static final String PROPERTY_AUDIT_ENABLED = "audit.enabled";
|
public static final String PROPERTY_AUDIT_ENABLED = "audit.enabled";
|
||||||
|
|
||||||
|
private static final String AUDITING_TO_DATABASE = ".auditingToDatabase";
|
||||||
|
private static final String AUDITING_TO_AUDIT_STORAGE = ".auditingToAuditStorage";
|
||||||
/** The name of the strict loading flag. */
|
/** The name of the strict loading flag. */
|
||||||
public static final String PROPERTY_AUDIT_CONFIG_STRICT = "audit.config.strict";
|
public static final String PROPERTY_AUDIT_CONFIG_STRICT = "audit.config.strict";
|
||||||
/** The XSD classpath location. */
|
/** The XSD classpath location. */
|
||||||
@@ -249,6 +252,26 @@ public class AuditModelRegistryImpl extends AbstractPropertyBackedBean implement
|
|||||||
return value != null && value.equalsIgnoreCase("true");
|
return value != null && value.equalsIgnoreCase("true");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isAuditingToDatabaseEnabled()
|
||||||
|
{
|
||||||
|
String value = getProperty(AUDIT_PROPERTY_AUDIT_ENABLED + AUDITING_TO_DATABASE);
|
||||||
|
return value == null || value.equalsIgnoreCase("true");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isAuditingToAuditStorageEnabled()
|
||||||
|
{
|
||||||
|
String value = getProperty(AUDIT_PROPERTY_AUDIT_ENABLED + AUDITING_TO_AUDIT_STORAGE);
|
||||||
|
return value != null && value.equalsIgnoreCase("true");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables audit and registers an audit model at a given URL. Does not register across the cluster and should only be used for unit test purposes.
|
* Enables audit and registers an audit model at a given URL. Does not register across the cluster and should only be used for unit test purposes.
|
||||||
*
|
*
|
||||||
@@ -296,6 +319,8 @@ public class AuditModelRegistryImpl extends AbstractPropertyBackedBean implement
|
|||||||
|
|
||||||
// Default value for global enabled property
|
// Default value for global enabled property
|
||||||
properties.put(AUDIT_PROPERTY_AUDIT_ENABLED, false);
|
properties.put(AUDIT_PROPERTY_AUDIT_ENABLED, false);
|
||||||
|
properties.put(AUDIT_PROPERTY_AUDIT_ENABLED + AUDITING_TO_DATABASE, true);
|
||||||
|
properties.put(AUDIT_PROPERTY_AUDIT_ENABLED + AUDITING_TO_AUDIT_STORAGE, false);
|
||||||
|
|
||||||
// Let's search for config files in the appropriate places. The individual applications they contain can still
|
// Let's search for config files in the appropriate places. The individual applications they contain can still
|
||||||
// be enabled/disabled by the bean properties
|
// be enabled/disabled by the bean properties
|
||||||
|
@@ -116,7 +116,7 @@ public class NodeDAOImpl extends AbstractNodeDAOImpl
|
|||||||
private static final String SELECT_NODE_MAX_ID = "alfresco.node.select_NodeMaxId";
|
private static final String SELECT_NODE_MAX_ID = "alfresco.node.select_NodeMaxId";
|
||||||
private static final String SELECT_NODE_INTERVAL_BY_TYPE = "alfresco.node.select_MinMaxNodeIdForNodeType";
|
private static final String SELECT_NODE_INTERVAL_BY_TYPE = "alfresco.node.select_MinMaxNodeIdForNodeType";
|
||||||
private static final String SELECT_NODES_WITH_ASPECT_IDS = "alfresco.node.select_NodesWithAspectIds";
|
private static final String SELECT_NODES_WITH_ASPECT_IDS = "alfresco.node.select_NodesWithAspectIds";
|
||||||
private static final String SELECT_NODES_WITH_ASPECT_IDS_LIMITED = "alfresco.node.select_NodesWithAspectIds_Limited";
|
private static final String SELECT_NODES_WITH_ASPECT_IDS_LIMITED = "alfresco.node.select.select_NodesWithAspectIds_Limited";
|
||||||
private static final String INSERT_NODE_ASSOC = "alfresco.node.insert.insert_NodeAssoc";
|
private static final String INSERT_NODE_ASSOC = "alfresco.node.insert.insert_NodeAssoc";
|
||||||
private static final String UPDATE_NODE_ASSOC = "alfresco.node.update_NodeAssoc";
|
private static final String UPDATE_NODE_ASSOC = "alfresco.node.update_NodeAssoc";
|
||||||
private static final String DELETE_NODE_ASSOC = "alfresco.node.delete_NodeAssoc";
|
private static final String DELETE_NODE_ASSOC = "alfresco.node.delete_NodeAssoc";
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -38,7 +38,7 @@ import org.alfresco.util.Pair;
|
|||||||
*/
|
*/
|
||||||
public enum EventJSONSchema
|
public enum EventJSONSchema
|
||||||
{
|
{
|
||||||
NODE_CREATED_V1("nodeCreated", 1, EventType.NODE_CREATED), NODE_UPDATED_V1("nodeUpdated", 1, EventType.NODE_UPDATED), NODE_DELETED_V1("nodeDeleted", 1, EventType.NODE_DELETED), CHILD_ASSOC_CREATED_V1("childAssocCreated", 1, EventType.CHILD_ASSOC_CREATED), CHILD_ASSOC_DELETED_V1("childAssocDeleted", 1, EventType.CHILD_ASSOC_DELETED), PEER_ASSOC_CREATED_V1("peerAssocCreated", 1, EventType.PEER_ASSOC_CREATED), PEER_ASSOC_DELETED_V1("peerAssocDeleted", 1, EventType.PEER_ASSOC_DELETED), PERMISSION_UPDATED_V1("permissionUpdated", 1, EventType.PERMISSION_UPDATED);
|
NODE_CREATED_V1("nodeCreated", 1, EventType.NODE_CREATED), NODE_UPDATED_V1("nodeUpdated", 1, EventType.NODE_UPDATED), NODE_DELETED_V1("nodeDeleted", 1, EventType.NODE_DELETED), CHILD_ASSOC_CREATED_V1("childAssocCreated", 1, EventType.CHILD_ASSOC_CREATED), CHILD_ASSOC_DELETED_V1("childAssocDeleted", 1, EventType.CHILD_ASSOC_DELETED), PEER_ASSOC_CREATED_V1("peerAssocCreated", 1, EventType.PEER_ASSOC_CREATED), PEER_ASSOC_DELETED_V1("peerAssocDeleted", 1, EventType.PEER_ASSOC_DELETED), PERMISSION_UPDATED_V1("permissionUpdated", 1, EventType.PERMISSION_UPDATED), AUDIT_ENTRY_CREATED_V1("auditEntryCreated", 1, EventType.AUDIT_ENTRY_CREATED);
|
||||||
|
|
||||||
private static final String PREFIX = "https://api.alfresco.com/schema/event/repo/v";
|
private static final String PREFIX = "https://api.alfresco.com/schema/event/repo/v";
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -124,6 +124,9 @@ public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcess
|
|||||||
/** Number of (bytecode) instructions that will trigger the observer */
|
/** Number of (bytecode) instructions that will trigger the observer */
|
||||||
private int observerInstructionCount = 100;
|
private int observerInstructionCount = 100;
|
||||||
|
|
||||||
|
/** Flag to enable or disable scope cleaning at the end of each script execution */
|
||||||
|
private boolean cleanScope = true;
|
||||||
|
|
||||||
/** Custom context factory */
|
/** Custom context factory */
|
||||||
public static AlfrescoContextFactory contextFactory;
|
public static AlfrescoContextFactory contextFactory;
|
||||||
|
|
||||||
@@ -210,6 +213,15 @@ public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcess
|
|||||||
this.observerInstructionCount = observerInstructionCount;
|
this.observerInstructionCount = observerInstructionCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param cleanScope
|
||||||
|
* true to enable scope cleaning at the end of each script execution - set to false to disable this feature.
|
||||||
|
*/
|
||||||
|
public void setCleanScope(boolean cleanScope)
|
||||||
|
{
|
||||||
|
this.cleanScope = cleanScope;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.alfresco.service.cmr.repository.ScriptProcessor#reset()
|
* @see org.alfresco.service.cmr.repository.ScriptProcessor#reset()
|
||||||
*/
|
*/
|
||||||
@@ -619,7 +631,7 @@ public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcess
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (!secure)
|
if (!secure && cleanScope)
|
||||||
{
|
{
|
||||||
unsetScope(model, scope);
|
unsetScope(model, scope);
|
||||||
}
|
}
|
||||||
|
@@ -81,11 +81,19 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
|||||||
|
|
||||||
public static final QName DEFAULT_RENDITION_CONTENT_PROP = ContentModel.PROP_CONTENT;
|
public static final QName DEFAULT_RENDITION_CONTENT_PROP = ContentModel.PROP_CONTENT;
|
||||||
public static final String DEFAULT_MIMETYPE = MimetypeMap.MIMETYPE_TEXT_PLAIN;
|
public static final String DEFAULT_MIMETYPE = MimetypeMap.MIMETYPE_TEXT_PLAIN;
|
||||||
|
public static final String MIMETYPE_METADATA_EXTRACT = "alfresco-metadata-extract";
|
||||||
|
public static final String MIMETYPE_METADATA_EMBED = "alfresco-metadata-embed";
|
||||||
public static final String DEFAULT_ENCODING = "UTF-8";
|
public static final String DEFAULT_ENCODING = "UTF-8";
|
||||||
|
|
||||||
public static final int SOURCE_HAS_NO_CONTENT = -1;
|
public static final int SOURCE_HAS_NO_CONTENT = -1;
|
||||||
public static final int RENDITION2_DOES_NOT_EXIST = -2;
|
public static final int RENDITION2_DOES_NOT_EXIST = -2;
|
||||||
|
|
||||||
|
// Allowed mimetypes to support text or metadata extract transforms when thumbnails are disabled.
|
||||||
|
private static final Set<String> ALLOWED_MIMETYPES = Set.of(
|
||||||
|
MimetypeMap.MIMETYPE_TEXT_PLAIN,
|
||||||
|
MIMETYPE_METADATA_EXTRACT,
|
||||||
|
MIMETYPE_METADATA_EMBED);
|
||||||
|
|
||||||
private static Log logger = LogFactory.getLog(RenditionService2Impl.class);
|
private static Log logger = LogFactory.getLog(RenditionService2Impl.class);
|
||||||
|
|
||||||
// As Async transforms and renditions are so similar, this class provides a way to provide the code that is different.
|
// As Async transforms and renditions are so similar, this class provides a way to provide the code that is different.
|
||||||
@@ -288,7 +296,7 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!isEnabled())
|
if (!isAsyncAllowed(renderOrTransform))
|
||||||
{
|
{
|
||||||
throw new RenditionService2Exception("Async transforms and renditions are disabled " +
|
throw new RenditionService2Exception("Async transforms and renditions are disabled " +
|
||||||
"(system.thumbnail.generate=false or renditionService2.enabled=false).");
|
"(system.thumbnail.generate=false or renditionService2.enabled=false).");
|
||||||
@@ -967,4 +975,24 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks if the given transform callback is a text extract transform for content indexing or metadata extract/embed.
|
||||||
|
private boolean isTextOrMetadataExtractTransform(RenderOrTransformCallBack renderOrTransform)
|
||||||
|
{
|
||||||
|
RenditionDefinition2 renditionDefinition = renderOrTransform.getRenditionDefinition();
|
||||||
|
return renditionDefinition != null && ALLOWED_MIMETYPES.contains(renditionDefinition.getTargetMimetype());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAsyncAllowed(RenderOrTransformCallBack renderOrTransform)
|
||||||
|
{
|
||||||
|
// If enabled is false, all async transforms/renditions must be blocked
|
||||||
|
if (!enabled)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If thumbnails are disabled, allow only text extract or metadata extract/embed transforms
|
||||||
|
return thumbnailsEnabled || isTextOrMetadataExtractTransform(renderOrTransform);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -74,7 +74,7 @@ import com.nimbusds.oauth2.sdk.id.Identifier;
|
|||||||
import com.nimbusds.oauth2.sdk.id.Issuer;
|
import com.nimbusds.oauth2.sdk.id.Issuer;
|
||||||
import com.nimbusds.openid.connect.sdk.claims.PersonClaims;
|
import com.nimbusds.openid.connect.sdk.claims.PersonClaims;
|
||||||
import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
|
import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.hc.client5.http.classic.HttpClient;
|
import org.apache.hc.client5.http.classic.HttpClient;
|
||||||
|
@@ -42,7 +42,7 @@ import jakarta.servlet.http.HttpServletResponse;
|
|||||||
import com.nimbusds.oauth2.sdk.Scope;
|
import com.nimbusds.oauth2.sdk.Scope;
|
||||||
import com.nimbusds.oauth2.sdk.id.Identifier;
|
import com.nimbusds.oauth2.sdk.id.Identifier;
|
||||||
import com.nimbusds.oauth2.sdk.id.State;
|
import com.nimbusds.oauth2.sdk.id.State;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
|
@@ -37,8 +37,9 @@
|
|||||||
<property name="properties" ref="global-properties" />
|
<property name="properties" ref="global-properties" />
|
||||||
</bean>
|
</bean>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="auditRecordReporter" ref="auditRecordReporter"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- User Audit Filter -->
|
<!-- User Audit Filter -->
|
||||||
|
|
||||||
<bean id="userAuditFilter" class="org.alfresco.repo.audit.UserAuditFilter">
|
<bean id="userAuditFilter" class="org.alfresco.repo.audit.UserAuditFilter">
|
||||||
@@ -108,5 +109,8 @@
|
|||||||
|
|
||||||
<!-- Reference in the audit registry managed bean -->
|
<!-- Reference in the audit registry managed bean -->
|
||||||
<alias name="Audit" alias="auditModel.modelRegistry"/>
|
<alias name="Audit" alias="auditModel.modelRegistry"/>
|
||||||
|
|
||||||
</beans>
|
<!-- Audit Record Reported -->
|
||||||
|
<bean id="auditRecordReporter" class="org.alfresco.repo.audit.AuditRecordReporterImpl"/>
|
||||||
|
|
||||||
|
</beans>
|
||||||
|
@@ -782,25 +782,6 @@
|
|||||||
<if test="ordered == true">order by node.id ASC</if>
|
<if test="ordered == true">order by node.id ASC</if>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="select_NodesWithAspectIds_Limited" parameterType="Ids" resultMap="result_NodeRef" >
|
|
||||||
select
|
|
||||||
node.id as id,
|
|
||||||
store.protocol as protocol,
|
|
||||||
store.identifier as identifier,
|
|
||||||
node.uuid as uuid
|
|
||||||
from
|
|
||||||
alf_node_aspects na
|
|
||||||
join alf_node node on (na.node_id = node.id)
|
|
||||||
left join alf_store store on (store.id = node.store_id)
|
|
||||||
where
|
|
||||||
<![CDATA[na.node_id >= #{idOne}]]>
|
|
||||||
<if test="idTwo != null"><![CDATA[and na.node_id < #{idTwo}]]></if>
|
|
||||||
and na.qname_id in
|
|
||||||
<foreach item="item" index="i" collection="ids" open="(" separator="," close=")">#{item}</foreach>
|
|
||||||
<if test="ordered == true">order by node.id ASC</if>
|
|
||||||
<if test="maxResults != null"><![CDATA[limit #{maxResults}]]></if>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<!-- Common results for result_NodeAssoc -->
|
<!-- Common results for result_NodeAssoc -->
|
||||||
<sql id="select_NodeAssoc_Results">
|
<sql id="select_NodeAssoc_Results">
|
||||||
select
|
select
|
||||||
@@ -1566,4 +1547,4 @@
|
|||||||
</foreach>
|
</foreach>
|
||||||
</delete>
|
</delete>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
@@ -30,4 +30,23 @@
|
|||||||
<![CDATA[and commit_time_ms <= #{maxCommitTime}]]>
|
<![CDATA[and commit_time_ms <= #{maxCommitTime}]]>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
</mapper>
|
<select id="select_NodesWithAspectIds_Limited" parameterType="Ids" resultMap="alfresco.node.result_NodeRef" >
|
||||||
|
select
|
||||||
|
node.id as id,
|
||||||
|
store.protocol as protocol,
|
||||||
|
store.identifier as identifier,
|
||||||
|
node.uuid as uuid
|
||||||
|
from
|
||||||
|
alf_node_aspects na
|
||||||
|
join alf_node node on (na.node_id = node.id)
|
||||||
|
left join alf_store store on (store.id = node.store_id)
|
||||||
|
where
|
||||||
|
<![CDATA[na.node_id >= #{idOne}]]>
|
||||||
|
<if test="idTwo != null"><![CDATA[and na.node_id < #{idTwo}]]></if>
|
||||||
|
and na.qname_id in
|
||||||
|
<foreach item="item" index="i" collection="ids" open="(" separator="," close=")">#{item}</foreach>
|
||||||
|
<if test="ordered == true">order by node.id ASC</if>
|
||||||
|
<if test="maxResults != null"><![CDATA[limit #{maxResults}]]></if>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
|
@@ -30,4 +30,23 @@
|
|||||||
<![CDATA[and commit_time_ms <= #{maxCommitTime}]]>
|
<![CDATA[and commit_time_ms <= #{maxCommitTime}]]>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
</mapper>
|
<select id="select_NodesWithAspectIds_Limited" parameterType="Ids" resultMap="alfresco.node.result_NodeRef" >
|
||||||
|
select
|
||||||
|
node.id as id,
|
||||||
|
store.protocol as protocol,
|
||||||
|
store.identifier as identifier,
|
||||||
|
node.uuid as uuid
|
||||||
|
from
|
||||||
|
alf_node_aspects na
|
||||||
|
join alf_node node on (na.node_id = node.id)
|
||||||
|
left join alf_store store on (store.id = node.store_id)
|
||||||
|
where
|
||||||
|
<![CDATA[na.node_id >= #{idOne}]]>
|
||||||
|
<if test="idTwo != null"><![CDATA[and na.node_id < #{idTwo}]]></if>
|
||||||
|
and na.qname_id in
|
||||||
|
<foreach item="item" index="i" collection="ids" open="(" separator="," close=")">#{item}</foreach>
|
||||||
|
<if test="ordered == true">order by node.id ASC</if>
|
||||||
|
<if test="maxResults != null"><![CDATA[limit #{maxResults}]]></if>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
|
@@ -286,6 +286,8 @@ audit.alfresco-access.enabled=false
|
|||||||
audit.alfresco-access.sub-actions.enabled=false
|
audit.alfresco-access.sub-actions.enabled=false
|
||||||
audit.cmischangelog.enabled=false
|
audit.cmischangelog.enabled=false
|
||||||
audit.dod5015.enabled=false
|
audit.dod5015.enabled=false
|
||||||
|
audit.enabled.auditingToAuditStorage=false
|
||||||
|
audit.enabled.auditingToDatabase=true
|
||||||
# Setting this flag to true will force startup failure when invalid audit configurations are detected
|
# Setting this flag to true will force startup failure when invalid audit configurations are detected
|
||||||
audit.config.strict=false
|
audit.config.strict=false
|
||||||
# Audit map filter for AccessAuditor - restricts recorded events to user driven events
|
# Audit map filter for AccessAuditor - restricts recorded events to user driven events
|
||||||
@@ -1394,6 +1396,9 @@ scripts.execution.maxMemoryUsedInBytes=-1
|
|||||||
# Number of instructions that will trigger the observer
|
# Number of instructions that will trigger the observer
|
||||||
scripts.execution.observerInstructionCount=5000
|
scripts.execution.observerInstructionCount=5000
|
||||||
|
|
||||||
|
# Flag to control if the scope is cleaned at the end of script execution
|
||||||
|
scripts.execution.clean.scope=true
|
||||||
|
|
||||||
# Default value being used in POST/size-details endpoint to partition a huge folder into smaller chunks
|
# Default value being used in POST/size-details endpoint to partition a huge folder into smaller chunks
|
||||||
# so that we can compute more efficiently and consolidate all sizes into a single unit.
|
# so that we can compute more efficiently and consolidate all sizes into a single unit.
|
||||||
default.async.folder.items=1000
|
default.async.folder.items=1000
|
||||||
|
@@ -60,6 +60,9 @@
|
|||||||
<property name="observerInstructionCount">
|
<property name="observerInstructionCount">
|
||||||
<value>${scripts.execution.observerInstructionCount}</value>
|
<value>${scripts.execution.observerInstructionCount}</value>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="cleanScope">
|
||||||
|
<value>${scripts.execution.clean.scope}</value>
|
||||||
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- base config implementation that script extension beans extend from - for auto registration
|
<!-- base config implementation that script extension beans extend from - for auto registration
|
||||||
|
@@ -48,6 +48,7 @@ import org.alfresco.util.testing.category.NonBuildTests;
|
|||||||
org.alfresco.repo.audit.UserAuditFilterTest.class,
|
org.alfresco.repo.audit.UserAuditFilterTest.class,
|
||||||
org.alfresco.repo.audit.AuditMethodInterceptorTest.class,
|
org.alfresco.repo.audit.AuditMethodInterceptorTest.class,
|
||||||
org.alfresco.repo.audit.access.AccessAuditorTest.class,
|
org.alfresco.repo.audit.access.AccessAuditorTest.class,
|
||||||
|
org.alfresco.repo.audit.AuditRecordUtilsTest.class,
|
||||||
|
|
||||||
// the following test will lock up the DB if run in the applicationContext_01 test suite
|
// the following test will lock up the DB if run in the applicationContext_01 test suite
|
||||||
org.alfresco.repo.activities.feed.FeedNotifierTest.class,
|
org.alfresco.repo.activities.feed.FeedNotifierTest.class,
|
||||||
|
@@ -877,6 +877,7 @@ public class AuditComponentTest extends TestCase
|
|||||||
auditModelRegistry.loadAuditModels();
|
auditModelRegistry.loadAuditModels();
|
||||||
|
|
||||||
auditModelRegistry.setProperty("audit.enabled", "true");
|
auditModelRegistry.setProperty("audit.enabled", "true");
|
||||||
|
auditModelRegistry.setProperty("audit.enabled.auditingToDatabase", "true");
|
||||||
|
|
||||||
auditModelRegistry.setProperty("audit.app1.enabled", "true");
|
auditModelRegistry.setProperty("audit.app1.enabled", "true");
|
||||||
auditModelRegistry.setProperty("audit.filter.app1.default.enabled", "true");
|
auditModelRegistry.setProperty("audit.filter.app1.default.enabled", "true");
|
||||||
|
@@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 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.audit;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
public class AuditRecordUtilsTest
|
||||||
|
{
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Test
|
||||||
|
public void testGenerateAuditRecordBuilderTest()
|
||||||
|
{
|
||||||
|
var testData = new HashMap<String, Serializable>();
|
||||||
|
|
||||||
|
testData.put("/alfresco-access/transaction/path", "/app:company_home");
|
||||||
|
testData.put("/alfresco-access/transaction/user", "admin");
|
||||||
|
testData.put("/alfresco-access/transaction/sub-actions", "updateNodeProperties");
|
||||||
|
var now = Instant.now();
|
||||||
|
testData.put("/alfresco-access/transaction/properties/from", (Serializable) Map.of(QName.createQName("modified"), Date.from(now)));
|
||||||
|
testData.put("/alfresco-access/transaction/properties/to", (Serializable) Map.of(QName.createQName("modified"), Date.from(now)));
|
||||||
|
|
||||||
|
var builder = AuditRecordUtils.generateAuditRecordBuilder(testData, "/alfresco-access/".length());
|
||||||
|
builder.setAuditRecordType("alfresco-access");
|
||||||
|
var auditRecord = builder.build();
|
||||||
|
|
||||||
|
assertNotNull(auditRecord);
|
||||||
|
assertEquals("alfresco-access", auditRecord.getAuditApplicationId());
|
||||||
|
|
||||||
|
var auditData = auditRecord.getAuditData();
|
||||||
|
assertEquals(1, auditData.size());
|
||||||
|
|
||||||
|
var transaction = (HashMap<String, ?>) auditData.get("transaction");
|
||||||
|
assertNotNull(transaction);
|
||||||
|
assertEquals(4, transaction.size());
|
||||||
|
assertEquals(testData.get("/alfresco-access/transaction/path"), transaction.get("path"));
|
||||||
|
assertEquals(testData.get("/alfresco-access/transaction/user"), transaction.get("user"));
|
||||||
|
assertEquals(testData.get("/alfresco-access/transaction/sub-actions"), transaction.get("sub-actions"));
|
||||||
|
|
||||||
|
var properties = (HashMap<String, Object>) transaction.get("properties");
|
||||||
|
assertNotNull(properties);
|
||||||
|
assertEquals(2, properties.size());
|
||||||
|
assertEquals(testData.get("/alfresco-access/transaction/properties/from"), properties.get("from"));
|
||||||
|
assertEquals(testData.get("/alfresco-access/transaction/properties/to"), properties.get("to"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Test
|
||||||
|
public void testGenerateAuditRecordBuilderTestNodeRef()
|
||||||
|
{
|
||||||
|
var testData = new HashMap<String, Serializable>();
|
||||||
|
var expectedValue = new HashMap<String, Serializable>();
|
||||||
|
|
||||||
|
expectedValue.put("nodeRef", new NodeRef("workspace://SpacesStore/bfa612e6-1a02-46a0-a612-e61a02e6a036"));
|
||||||
|
expectedValue.put("objectId", "bfa612e6-1a02-46a0-a612-e61a02e6a036;1.0");
|
||||||
|
|
||||||
|
testData.put("/CMISChangeLog/CREATED/result/value", expectedValue);
|
||||||
|
|
||||||
|
var builder = AuditRecordUtils.generateAuditRecordBuilder(testData, "/CMISChangeLog/".length());
|
||||||
|
builder.setAuditRecordType("CMISChangeLog");
|
||||||
|
var auditRecord = builder.build();
|
||||||
|
|
||||||
|
assertNotNull(auditRecord);
|
||||||
|
|
||||||
|
assertEquals("CMISChangeLog", auditRecord.getAuditApplicationId());
|
||||||
|
|
||||||
|
var auditData = auditRecord.getAuditData();
|
||||||
|
assertEquals(1, auditData.size());
|
||||||
|
|
||||||
|
var created = (HashMap<String, ?>) auditData.get("CREATED");
|
||||||
|
assertNotNull(created);
|
||||||
|
|
||||||
|
assertEquals(1, created.size());
|
||||||
|
var result = (HashMap<String, Object>) created.get("result");
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(1, result.size());
|
||||||
|
|
||||||
|
var resultValue = (HashMap<String, Object>) result.get("value");
|
||||||
|
assertNotNull(resultValue);
|
||||||
|
assertEquals(2, resultValue.size());
|
||||||
|
|
||||||
|
var expectedNodeRef = (NodeRef) expectedValue.get("nodeRef");
|
||||||
|
assertEquals(expectedNodeRef.getId(), resultValue.get("nodeRef"));
|
||||||
|
assertEquals(expectedValue.get("objectId"), resultValue.get("objectId"));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -50,6 +50,7 @@ public class AuditTestSuite extends TestSuite
|
|||||||
suite.addTestSuite(UserAuditFilterTest.class);
|
suite.addTestSuite(UserAuditFilterTest.class);
|
||||||
suite.addTestSuite(AuditMethodInterceptorTest.class);
|
suite.addTestSuite(AuditMethodInterceptorTest.class);
|
||||||
|
|
||||||
|
suite.addTest(new JUnit4TestAdapter(AuditRecordUtilsTest.class));
|
||||||
suite.addTest(new JUnit4TestAdapter(PropertyAuditFilterTest.class));
|
suite.addTest(new JUnit4TestAdapter(PropertyAuditFilterTest.class));
|
||||||
suite.addTest(new JUnit4TestAdapter(AccessAuditorTest.class));
|
suite.addTest(new JUnit4TestAdapter(AccessAuditorTest.class));
|
||||||
|
|
||||||
|
@@ -39,6 +39,7 @@ import org.junit.Test;
|
|||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.model.RenditionModel;
|
import org.alfresco.model.RenditionModel;
|
||||||
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
@@ -776,4 +777,58 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTextExtractTransformAllowedWhenThumbnailDisabled()
|
||||||
|
{
|
||||||
|
// create a source node
|
||||||
|
NodeRef sourceNodeRef = createSource(ADMIN, "quick.pdf");
|
||||||
|
assertNotNull("Node not generated", sourceNodeRef);
|
||||||
|
String replyQueue = "org.test.queue";
|
||||||
|
String targetMimetype = MimetypeMap.MIMETYPE_TEXT_PLAIN;
|
||||||
|
|
||||||
|
TransformDefinition textExtractTransform = new TransformDefinition(
|
||||||
|
targetMimetype,
|
||||||
|
java.util.Collections.emptyMap(),
|
||||||
|
"clientData",
|
||||||
|
replyQueue,
|
||||||
|
"requestId");
|
||||||
|
|
||||||
|
renditionService2.setThumbnailsEnabled(false);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Should NOT throw, as this is a text extract transform
|
||||||
|
AuthenticationUtil.runAs(() -> {
|
||||||
|
transactionService.getRetryingTransactionHelper().doInTransaction(() -> {
|
||||||
|
renditionService2.transform(sourceNodeRef, textExtractTransform);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
}, ADMIN);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
renditionService2.setThumbnailsEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMetadataExtractTransformAllowedWhenThumbnailDisabled()
|
||||||
|
{
|
||||||
|
// create a source node
|
||||||
|
NodeRef sourceNodeRef = createSource(ADMIN, "quick.pdf");
|
||||||
|
assertNotNull("Node not generated", sourceNodeRef);
|
||||||
|
renditionService2.setThumbnailsEnabled(false);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Should NOT throw, as this is a metadata extract transform
|
||||||
|
extract(ADMIN, sourceNodeRef);
|
||||||
|
waitForExtract(ADMIN, sourceNodeRef, true);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
renditionService2.setThumbnailsEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user