Compare commits

..

35 Commits

Author SHA1 Message Date
alfresco-build
3c245ae64c [maven-release-plugin][skip ci] prepare release 25.2.0.46 2025-06-17 10:30:49 +00:00
tathagta15
fbf5966d10 ACS-9745-removed-reportPortal-integration (#3383) 2025-06-17 15:04:33 +05:30
alfresco-build
8fca14df40 [maven-release-plugin][skip ci] prepare for next development iteration 2025-06-15 00:08:17 +00:00
alfresco-build
e38e7b4bda [maven-release-plugin][skip ci] prepare release 25.2.0.45 2025-06-15 00:08:15 +00:00
Alfresco CI User
b378de58d8 [force] Force release for 2025-06-15. 2025-06-15 00:05:16 +00:00
alfresco-build
8a64d9fb0b [maven-release-plugin][skip ci] prepare for next development iteration 2025-06-11 10:29:56 +00:00
alfresco-build
3c092b696d [maven-release-plugin][skip ci] prepare release 25.2.0.44 2025-06-11 10:29:54 +00:00
Damian Ujma
6f222106c5 MNT-25089 Bump ATS to 4.1.8-A1 (#3384) 2025-06-11 11:48:13 +02:00
alfresco-build
bd5a016382 [maven-release-plugin][skip ci] prepare for next development iteration 2025-06-11 09:24:32 +00:00
alfresco-build
dc24718717 [maven-release-plugin][skip ci] prepare release 25.2.0.43 2025-06-11 09:24:30 +00:00
Piotr Żurek
e65614d3c2 Trigger CI 2025-06-11 10:31:40 +02:00
alfresco-build
698f9b15ce [maven-release-plugin][skip ci] prepare for next development iteration 2025-06-08 00:08:13 +00:00
alfresco-build
09a254e5fd [maven-release-plugin][skip ci] prepare release 25.2.0.42 2025-06-08 00:08:11 +00:00
Alfresco CI User
6f442a703a [force] Force release for 2025-06-08. 2025-06-08 00:05:12 +00:00
alfresco-build
f1862c9636 [maven-release-plugin][skip ci] prepare for next development iteration 2025-06-04 08:13:48 +00:00
alfresco-build
231075fd5e [maven-release-plugin][skip ci] prepare release 25.2.0.41 2025-06-04 08:13:46 +00:00
jakubkochman
979420879c ACS-9646 removed extra space that broke the escaping logic (#3374) 2025-06-04 09:21:31 +02:00
alfresco-build
db330e28f5 [maven-release-plugin][skip ci] prepare for next development iteration 2025-06-03 05:02:09 +00:00
alfresco-build
bae0573636 [maven-release-plugin][skip ci] prepare release 25.2.0.40 2025-06-03 05:02:07 +00:00
SatyamSah5
8089fc2572 [ACS-9697] Added user-friendly error message. (#3371) 2025-06-03 09:41:57 +05:30
alfresco-build
1c4fe53c0f [maven-release-plugin][skip ci] prepare for next development iteration 2025-06-01 00:09:36 +00:00
alfresco-build
7a8aa1a2c1 [maven-release-plugin][skip ci] prepare release 25.2.0.39 2025-06-01 00:09:34 +00:00
Alfresco CI User
e08ba1fd4f [force] Force release for 2025-06-01. 2025-06-01 00:05:59 +00:00
alfresco-build
4f40bd0687 [maven-release-plugin][skip ci] prepare for next development iteration 2025-05-29 09:34:20 +00:00
alfresco-build
a3578f7baa [maven-release-plugin][skip ci] prepare release 25.2.0.38 2025-05-29 09:34:18 +00:00
jakubkochman
8e8b9c868f ACS-9635 bumped httpclient5 to 5.5 to fix CVE-2025-27820(#3369) 2025-05-29 10:53:01 +02:00
cezary-witkowski
f77b3b79e5 [MNT-24859] Basic Auth still possible with Keycloak enabled (#3361)
Signed-off-by: cezary-witkowski <cezary.witkowski@hyland.com>
Co-authored-by: Sathish Kumar <ST28@ford.com>
Co-authored-by: pmm <purusothaman.mm@hyland.com>
Co-authored-by: purusothaman-mm <purusothman.mm@hyland.com>
2025-05-27 13:31:00 +02:00
alfresco-build
3a7157f4a7 [maven-release-plugin][skip ci] prepare for next development iteration 2025-05-26 16:46:11 +00:00
alfresco-build
d6b979f341 [maven-release-plugin][skip ci] prepare release 25.2.0.37 2025-05-26 16:46:09 +00:00
varapathijanakiram
a090de4e71 Merge pull request #3367 from Alfresco/revert-3333-fix/MNT-24776
Revert "Fix category picker visibility to show only permitted categories based on local permissions"
2025-05-26 21:33:31 +05:30
varapathijanakiram
03621db30a Revert "Fix category picker visibility to show only permitted categories base…"
This reverts commit 8645cdc76d.
2025-05-26 20:45:15 +05:30
alfresco-build
766a6def2b [maven-release-plugin][skip ci] prepare for next development iteration 2025-05-25 00:08:54 +00:00
alfresco-build
117804fb68 [maven-release-plugin][skip ci] prepare release 25.2.0.36 2025-05-25 00:08:52 +00:00
Alfresco CI User
f03e6761ce [force] Force release for 2025-05-25. 2025-05-25 00:05:09 +00:00
alfresco-build
74c8288206 [maven-release-plugin][skip ci] prepare for next development iteration 2025-05-23 12:33:45 +00:00
73 changed files with 964 additions and 1107 deletions

View File

@@ -29,9 +29,6 @@ env:
AUTH0_CLIENT_ID: ${{ secrets.AUTH0_OIDC_ADMIN_CLIENT_ID }}
AUTH0_CLIENT_SECRET: ${{ secrets.AUTH0_OIDC_CLIENT_SECRET }}
AUTH0_ADMIN_PASSWORD: ${{ secrets.AUTH0_OIDC_ADMIN_PASSWORD }}
# Report Portal settings
RP_LAUNCH_PREFIX: "${{ github.workflow }} - ${{ github.job }}"
RP_PROJECT: alfresco-backend
jobs:
prepare:
@@ -182,52 +179,9 @@ jobs:
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
- name: "Init"
run: bash ./scripts/ci/init.sh
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} - ${{ matrix.testModule }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl ${{ matrix.testModule }} -am ${{ matrix.testAttributes }} -DfailIfNoTests=false "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
echo "::error title=run-tests::Tests failed: re-throwing on error."
exit 1
- name: "Clean Maven cache"
run: bash ./scripts/ci/cleanup_cache.sh
@@ -270,52 +224,8 @@ jobs:
- name: "Set up the environment"
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile ${{ matrix.compose-profile }} up -d
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} - ${{ matrix.testSuite }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl remote-api -Dtest=${{ matrix.testSuite }} -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
echo "::error title=run-tests::Tests failed: re-throwing on error."
exit 1
run: mvn -B test -pl remote-api -Dtest=${{ matrix.testSuite }} -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco # pragma: allowlist secret
- name: "Clean Maven cache"
run: bash ./scripts/ci/cleanup_cache.sh
@@ -345,52 +255,8 @@ jobs:
run: docker compose -f ./scripts/ci/docker-compose/docker-compose-db.yaml --profile mariadb up -d
env:
MARIADB_VERSION: ${{ matrix.version }}
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} - ${{ matrix.version }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.name=alfresco -Ddb.url=jdbc:mariadb://localhost:3307/alfresco?useUnicode=yes\&characterEncoding=UTF-8 -Ddb.username=alfresco -Ddb.password=alfresco -Ddb.driver=org.mariadb.jdbc.Driver "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
echo "::error title=run-tests::Tests failed: re-throwing on error."
exit 1
run: mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.name=alfresco -Ddb.url=jdbc:mariadb://localhost:3307/alfresco?useUnicode=yes\&characterEncoding=UTF-8 -Ddb.username=alfresco -Ddb.password=alfresco -Ddb.driver=org.mariadb.jdbc.Driver # pragma: allowlist secret
- name: "Clean Maven cache"
run: bash ./scripts/ci/cleanup_cache.sh
@@ -416,52 +282,8 @@ jobs:
run: docker compose -f ./scripts/ci/docker-compose/docker-compose-db.yaml --profile mariadb up -d
env:
MARIADB_VERSION: 10.11
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.name=alfresco -Ddb.url=jdbc:mariadb://localhost:3307/alfresco?useUnicode=yes\&characterEncoding=UTF-8 -Ddb.username=alfresco -Ddb.password=alfresco -Ddb.driver=org.mariadb.jdbc.Driver "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
echo "::error title=run-tests::Tests failed: re-throwing on error."
exit 1
run: mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.name=alfresco -Ddb.url=jdbc:mariadb://localhost:3307/alfresco?useUnicode=yes\&characterEncoding=UTF-8 -Ddb.username=alfresco -Ddb.password=alfresco -Ddb.driver=org.mariadb.jdbc.Driver # pragma: allowlist secret
- name: "Clean Maven cache"
run: bash ./scripts/ci/cleanup_cache.sh
@@ -487,52 +309,8 @@ jobs:
run: docker compose -f ./scripts/ci/docker-compose/docker-compose-db.yaml --profile mysql up -d
env:
MYSQL_VERSION: 8
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=com.mysql.cj.jdbc.Driver -Ddb.name=alfresco -Ddb.url=jdbc:mysql://localhost:3307/alfresco -Ddb.username=alfresco -Ddb.password=alfresco "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
echo "::error title=run-tests::Tests failed: re-throwing on error."
exit 1
run: mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=com.mysql.jdbc.Driver -Ddb.name=alfresco -Ddb.url=jdbc:mysql://localhost:3307/alfresco -Ddb.username=alfresco -Ddb.password=alfresco # pragma: allowlist secret
- name: "Clean Maven cache"
run: bash ./scripts/ci/cleanup_cache.sh
@@ -557,52 +335,8 @@ jobs:
run: docker compose -f ./scripts/ci/docker-compose/docker-compose-db.yaml --profile postgres up -d
env:
POSTGRES_VERSION: 14.15
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
echo "::error title=run-tests::Tests failed: re-throwing on error."
exit 1
run: mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco # pragma: allowlist secret
- name: "Clean Maven cache"
run: bash ./scripts/ci/cleanup_cache.sh
@@ -627,52 +361,8 @@ jobs:
run: docker compose -f ./scripts/ci/docker-compose/docker-compose-db.yaml --profile postgres up -d
env:
POSTGRES_VERSION: 15.10
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
echo "::error title=run-tests::Tests failed: re-throwing on error."
exit 1
run: mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco # pragma: allowlist secret
- name: "Clean Maven cache"
run: bash ./scripts/ci/cleanup_cache.sh
@@ -697,52 +387,8 @@ jobs:
run: docker compose -f ./scripts/ci/docker-compose/docker-compose-db.yaml --profile postgres up -d
env:
POSTGRES_VERSION: 16.6
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
echo "::error title=run-tests::Tests failed: re-throwing on error."
exit 1
run: mvn -B test -pl repository -am -Dtest=AllDBTestsTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco # pragma: allowlist secret
- name: "Clean Maven cache"
run: bash ./scripts/ci/cleanup_cache.sh
@@ -763,52 +409,8 @@ jobs:
run: bash ./scripts/ci/init.sh
- name: "Run ActiveMQ"
run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile activemq up -d
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl repository -am -Dtest=MessagingUnitTestSuite -DfailIfNoTests=false "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
echo "::error title=run-tests::Tests failed: re-throwing on error."
exit 1
run: mvn -B test -pl repository -am -Dtest=CamelRoutesTest,CamelComponentsTest -DfailIfNoTests=false # pragma: allowlist secret
- name: "Clean Maven cache"
run: bash ./scripts/ci/cleanup_cache.sh
@@ -879,52 +481,8 @@ jobs:
- name: "Set up the environment"
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile ${{ matrix.compose-profile }} up -d
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} - ${{ matrix.testSuite }} ${{ matrix.idp }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl repository -am -Dtest=${{ matrix.testSuite }} -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco ${{ matrix.mvn-options }} "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
echo "::error title=run-tests::Tests failed: re-throwing on error."
exit 1
run: mvn -B test -pl repository -am -Dtest=${{ matrix.testSuite }} -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco ${{ matrix.mvn-options }} # pragma: allowlist secret
- name: "Clean Maven cache"
run: bash ./scripts/ci/cleanup_cache.sh
@@ -986,59 +544,16 @@ jobs:
- name: "Build TAS integration tests"
if: ${{ matrix.test-name }} == 'Integration TAS tests'
run: mvn install -pl :alfresco-community-repo-integration-test -am -DskipTests -Pall-tas-tests
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} - ${{ matrix.test-name }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: tests
env:
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
run: |
eval "args=($RP_OPTS)"
mvn -B verify -f packaging/tests/${{ matrix.pom-dir }}/pom.xml -Pall-tas-tests,${{ matrix.test-profile }} -Denvironment=default -DrunBugs=false "${args[@]}"
continue-on-error: true
run: mvn -B verify -f packaging/tests/${{ matrix.pom-dir }}/pom.xml -Pall-tas-tests,${{ matrix.test-profile }} -Denvironment=default -DrunBugs=false
- name: "Print output after success"
if: ${{ always() && steps.tests.outcome == 'success' }}
run: ${TAS_SCRIPTS}/output_tests_run.sh "packaging/tests/${{ matrix.pom-dir }}"
- name: "Print output after failure"
if: ${{ always() && steps.tests.outcome == 'failure' }}
run: ${TAS_SCRIPTS}/output_logs_for_failures.sh "packaging/tests/${{ matrix.pom-dir }}"
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
id: rp-summarize
with:
tests-outcome: ${{ steps.tests.outcome }}
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.tests.outcome != 'success'
run: |
echo "::error title=tests::Tests failed: re-throwing on error."
exit 1
- name: "Clean Maven cache"
run: bash ./scripts/ci/cleanup_cache.sh
@@ -1059,52 +574,8 @@ jobs:
run: bash ./scripts/ci/init.sh
- name: "Run Postgres 16.6 database"
run: docker compose -f ./scripts/ci/docker-compose/docker-compose.yaml --profile postgres up -d
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Run tests"
id: run-tests
env:
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl :alfresco-share-services -am -Dtest=ShareServicesTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
echo "::error title=run-tests::Tests failed: re-throwing on error."
exit 1
run: mvn -B test -pl :alfresco-share-services -am -Dtest=ShareServicesTestSuite -DfailIfNoTests=false -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco # pragma: allowlist secret
- name: "Clean Maven cache"
run: bash ./scripts/ci/cleanup_cache.sh
@@ -1134,23 +605,9 @@ jobs:
run: |
bash ./scripts/ci/init.sh
bash ./scripts/ci/build.sh
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} 0${{ matrix.part }} - (PostgreSQL) ${{ matrix.test-name }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Verify"
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
env:
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn --file amps/ags/pom.xml -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-postgres -PagsAllTestSuitePt${{ matrix.part }} ${{ env.LOG_WARN }} "${args[@]}"
run: mvn --file amps/ags/pom.xml -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-postgres -PagsAllTestSuitePt${{ matrix.part }} ${{ env.LOG_WARN }}
- name: "Clean Maven cache"
run: bash ./scripts/ci/cleanup_cache.sh
@@ -1180,23 +637,9 @@ jobs:
run: |
bash ./scripts/ci/init.sh
bash ./scripts/ci/build.sh
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }} 0${{ matrix.part }} - (MySQL) ${{ matrix.test-name }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Verify"
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
env:
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn --file amps/ags/pom.xml -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-mysql -PagsAllTestSuitePt${{ matrix.part }} ${{ env.LOG_WARN }} "${args[@]}"
run: mvn --file amps/ags/pom.xml -B verify -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Pags -Pstart-mysql -PagsAllTestSuitePt${{ matrix.part }} ${{ env.LOG_WARN }}
- name: "Clean Maven cache"
run: bash ./scripts/ci/cleanup_cache.sh
@@ -1228,53 +671,9 @@ jobs:
${{ env.TAS_SCRIPTS }}/start-compose.sh ./amps/ags/rm-community/rm-community-repo/docker-compose.yml
${{ env.TAS_SCRIPTS }}/wait-for-alfresco-start.sh "http://localhost:8080/alfresco"
mvn -B install -pl :alfresco-governance-services-automation-community-rest-api -am -Pags -Pall-tas-tests -DskipTests
- name: "Prepare Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v8.16.0
id: rp-prepare
with:
rp-launch-prefix: ${{ env.RP_LAUNCH_PREFIX }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
rp-project: ${{ env.RP_PROJECT }}
rp-use-static-launch-name: true
continue-on-error: true
- name: "Add GitHub Step Summary"
if: github.ref_name == 'master'
env:
RP_ENABLED: ${{ steps.rp-prepare.outputs.enabled }}
RP_KEY: ${{ steps.rp-prepare.outputs.key }}
RP_URL: ${{ steps.rp-prepare.outputs.url }}
run: bash scripts/ci/add_step_summary.sh
continue-on-error: true
- name: "Test"
id: run-tests
timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }}
env:
RP_OPTS: ${{ github.ref_name == 'master' && steps.rp-prepare.outputs.mvn-opts || '' }}
run: |
eval "args=($RP_OPTS)"
mvn -B test -pl :alfresco-governance-services-automation-community-rest-api -Dskip.automationtests=false -Pags -Pall-tas-tests "${args[@]}"
continue-on-error: true
- name: "Update GitHub Step Summary"
if: github.ref_name == 'master'
run: |
echo "#### ⏱ After Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
continue-on-error: true
- name: "Summarize Report Portal"
if: github.ref_name == 'master'
uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-summarize@v8.16.0
id: rp-summarize
with:
tests-outcome: ${{ steps.run-tests.outcome }}
rp-launch-key: ${{ steps.rp-prepare.outputs.key }}
rp-project: ${{ env.RP_PROJECT }}
rp-token: ${{ secrets.REPORT_PORTAL_TOKEN }}
continue-on-error: true
- name: "Exit on failure"
if: steps.run-tests.outcome != 'success'
run: |
echo "::error title=run-tests::Tests failed: re-throwing on error."
exit 1
run: mvn -B test -pl :alfresco-governance-services-automation-community-rest-api -Dskip.automationtests=false -Pags -Pall-tas-tests
- name: "Configure AWS credentials"
if: ${{ always() }}
uses: aws-actions/configure-aws-credentials@v4

View File

@@ -127,29 +127,6 @@
}
],
"results": {
".github/workflows/ci.yml": [
{
"type": "Secret Keyword",
"filename": ".github/workflows/ci.yml",
"hashed_secret": "b86dc2f033a63f2b7b9e7d270ab806d2910d7572",
"is_verified": false,
"line_number": 295
},
{
"type": "Secret Keyword",
"filename": ".github/workflows/ci.yml",
"hashed_secret": "1bfb0e20f886150ba59b853bcd49dea893e00966",
"is_verified": false,
"line_number": 370
},
{
"type": "Secret Keyword",
"filename": ".github/workflows/ci.yml",
"hashed_secret": "128f14373ccfaff49e3664045d3a11b50cbb7b39",
"is_verified": false,
"line_number": 904
}
],
".github/workflows/master_release.yml": [
{
"type": "Secret Keyword",
@@ -1273,7 +1250,7 @@
"filename": "repository/src/main/resources/alfresco/repository.properties",
"hashed_secret": "84551ae5442affc9f1a2d3b4c86ae8b24860149d",
"is_verified": false,
"line_number": 770,
"line_number": 771,
"is_secret": false
}
],
@@ -1868,5 +1845,5 @@
}
]
},
"generated_at": "2025-03-27T23:45:41Z"
"generated_at": "2025-06-09T16:43:14Z"
}

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-amps</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
</parent>
<modules>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-parent</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
</parent>
<modules>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
</parent>
<build>
@@ -74,16 +74,6 @@
<artifactId>alfresco-testng</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>

View File

@@ -1 +0,0 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-parent</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
</parent>
<modules>

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
</parent>
<properties>
@@ -84,11 +84,6 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>

View File

@@ -1 +0,0 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -1 +0,0 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

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

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
</parent>
<modules>

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-amps</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
</parent>
<properties>
@@ -70,11 +70,6 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>

View File

@@ -1 +0,0 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
</parent>
<dependencies>
@@ -126,11 +126,6 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>

View File

@@ -1 +0,0 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
</parent>
<properties>
@@ -247,11 +247,6 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>gunit</artifactId>

View File

@@ -1 +0,0 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
</parent>
<dependencies>
@@ -46,11 +46,6 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>

View File

@@ -1 +0,0 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

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

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
</parent>
<properties>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
</parent>
<modules>

View File

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

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
</parent>
<organization>
@@ -68,16 +68,6 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@@ -1 +0,0 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
</parent>
<developers>
@@ -36,11 +36,6 @@
<artifactId>jakarta.mail-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@@ -1 +0,0 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
</parent>
<developers>
@@ -44,18 +44,6 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>

View File

@@ -1 +0,0 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
</parent>
<properties>
@@ -79,18 +79,6 @@
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2022 Alfresco Software Limited
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -747,7 +747,7 @@ public class CreateRulesTests extends RulesRestTest
.createSingleRule(ruleModel);
restClient.assertStatusCodeIs(NOT_FOUND);
restClient.assertLastError().containsSummary("The entity with id: non-existent-node was not found");
restClient.assertLastError().containsSummary("Destination folder having Id: non-existent-node no longer exists. Please update your rule definition.");
}
/**

View File

@@ -1 +0,0 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
</parent>
<developers>
@@ -31,11 +31,6 @@
<artifactId>webdav</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@@ -1 +0,0 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
</parent>
<properties>

30
pom.xml
View File

@@ -2,7 +2,7 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>alfresco-community-repo</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
<packaging>pom</packaging>
<name>Alfresco Community Repo Parent</name>
@@ -51,8 +51,8 @@
<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.version>5.23.0</dependency.activiti.version>
<dependency.alfresco-transform-core.version>5.1.7</dependency.alfresco-transform-core.version>
<dependency.alfresco-transform-service.version>4.1.7</dependency.alfresco-transform-service.version>
<dependency.alfresco-transform-core.version>5.1.8-A.1</dependency.alfresco-transform-core.version>
<dependency.alfresco-transform-service.version>4.1.8-A.1</dependency.alfresco-transform-service.version>
<dependency.alfresco-greenmail.version>7.1</dependency.alfresco-greenmail.version>
<dependency.acs-event-model.version>1.0.2</dependency.acs-event-model.version>
@@ -74,8 +74,9 @@
<dependency.guava.version>33.3.1-jre</dependency.guava.version>
<dependency.httpclient.version>4.5.14</dependency.httpclient.version>
<dependency.httpcore.version>4.4.16</dependency.httpcore.version>
<dependency.httpcomponents-httpclient5.version>5.4.1</dependency.httpcomponents-httpclient5.version>
<dependency.httpcomponents-httpcore5.version>5.3.3</dependency.httpcomponents-httpcore5.version>
<dependency.httpcomponents-httpclient5.version>5.5</dependency.httpcomponents-httpclient5.version>
<dependency.httpcomponents-httpcore5.version>5.3.4</dependency.httpcomponents-httpcore5.version>
<dependency.httpcomponents-httpcore5-h2.version>5.3.4</dependency.httpcomponents-httpcore5-h2.version>
<dependency.commons-httpclient.version>3.1-HTTPCLIENT-1265</dependency.commons-httpclient.version>
<dependency.xercesImpl.version>2.12.2</dependency.xercesImpl.version>
<dependency.slf4j.version>2.0.16</dependency.slf4j.version>
@@ -153,7 +154,7 @@
<connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
<developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
<url>https://github.com/Alfresco/alfresco-community-repo</url>
<tag>25.2.0.35</tag>
<tag>25.2.0.46</tag>
</scm>
<distributionManagement>
@@ -400,6 +401,11 @@
<artifactId>httpcore5</artifactId>
<version>${dependency.httpcomponents-httpcore5.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.core5</groupId>
<artifactId>httpcore5-h2</artifactId>
<version>${dependency.httpcomponents-httpcore5-h2.version}</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
@@ -822,18 +828,6 @@
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<version>5.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>gunit</artifactId>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
</parent>
<dependencies>
@@ -66,11 +66,6 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -46,7 +46,7 @@ import org.alfresco.repo.management.subsystems.ActivateableBean;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.external.AdminConsoleAuthenticator;
import org.alfresco.repo.security.authentication.external.ExternalUserAuthenticator;
import org.alfresco.repo.security.authentication.external.RemoteUserMapper;
import org.alfresco.repo.web.auth.AuthenticationListener;
import org.alfresco.repo.web.auth.TicketCredentials;
@@ -71,9 +71,11 @@ public class RemoteUserAuthenticatorFactory extends BasicHttpAuthenticatorFactor
protected RemoteUserMapper remoteUserMapper;
protected AuthenticationComponent authenticationComponent;
protected AdminConsoleAuthenticator adminConsoleAuthenticator;
protected ExternalUserAuthenticator adminConsoleAuthenticator;
protected ExternalUserAuthenticator webScriptsHomeAuthenticator;
private boolean alwaysAllowBasicAuthForAdminConsole = true;
private boolean alwaysAllowBasicAuthForWebScriptsHome = true;
List<String> adminConsoleScriptFamilies;
long getRemoteUserTimeoutMilliseconds = GET_REMOTE_USER_TIMEOUT_MILLISECONDS_DEFAULT;
@@ -97,6 +99,16 @@ public class RemoteUserAuthenticatorFactory extends BasicHttpAuthenticatorFactor
this.alwaysAllowBasicAuthForAdminConsole = alwaysAllowBasicAuthForAdminConsole;
}
public boolean isAlwaysAllowBasicAuthForWebScriptsHome()
{
return alwaysAllowBasicAuthForWebScriptsHome;
}
public void setAlwaysAllowBasicAuthForWebScriptsHome(boolean alwaysAllowBasicAuthForWebScriptsHome)
{
this.alwaysAllowBasicAuthForWebScriptsHome = alwaysAllowBasicAuthForWebScriptsHome;
}
public List<String> getAdminConsoleScriptFamilies()
{
return adminConsoleScriptFamilies;
@@ -118,11 +130,17 @@ public class RemoteUserAuthenticatorFactory extends BasicHttpAuthenticatorFactor
}
public void setAdminConsoleAuthenticator(
AdminConsoleAuthenticator adminConsoleAuthenticator)
ExternalUserAuthenticator adminConsoleAuthenticator)
{
this.adminConsoleAuthenticator = adminConsoleAuthenticator;
}
public void setWebScriptsHomeAuthenticator(
ExternalUserAuthenticator webScriptsHomeAuthenticator)
{
this.webScriptsHomeAuthenticator = webScriptsHomeAuthenticator;
}
@Override
public Authenticator create(WebScriptServletRequest req, WebScriptServletResponse res)
{
@@ -136,6 +154,8 @@ public class RemoteUserAuthenticatorFactory extends BasicHttpAuthenticatorFactor
*/
public class RemoteUserAuthenticator extends BasicHttpAuthenticator
{
private static final String WEB_SCRIPTS_BASE_PATH = "org/springframework/extensions/webscripts";
public RemoteUserAuthenticator(WebScriptServletRequest req, WebScriptServletResponse res, AuthenticationListener listener)
{
super(req, res, listener);
@@ -156,24 +176,47 @@ public class RemoteUserAuthenticatorFactory extends BasicHttpAuthenticatorFactor
{
if (servletReq.getServiceMatch() != null &&
isAdminConsoleWebScript(servletReq.getServiceMatch().getWebScript()) && isAdminConsoleAuthenticatorActive())
isAdminConsole(servletReq.getServiceMatch().getWebScript()) && isAdminConsoleAuthenticatorActive())
{
userId = getAdminConsoleUser();
}
else if (servletReq.getServiceMatch() != null &&
isWebScriptsHome(servletReq.getServiceMatch().getWebScript()) && isWebScriptsHomeAuthenticatorActive())
{
userId = getWebScriptsHomeUser();
}
if (userId == null)
{
if (isAlwaysAllowBasicAuthForAdminConsole())
{
final boolean useTimeoutForAdminAccessingAdminConsole = shouldUseTimeoutForAdminAccessingAdminConsole(required, isGuest);
boolean shouldUseTimeout = shouldUseTimeoutForAdminAccessingAdminConsole(required, isGuest);
if (useTimeoutForAdminAccessingAdminConsole && isBasicAuthHeaderPresentForAdmin())
if (shouldUseTimeout && isBasicAuthHeaderPresentForAdmin())
{
return callBasicAuthForAdminConsoleAccess(required, isGuest);
return callBasicAuthForAdminConsoleOrWebScriptsHomeAccess(required, isGuest);
}
try
{
userId = getRemoteUserWithTimeout(useTimeoutForAdminAccessingAdminConsole);
userId = getRemoteUserWithTimeout(shouldUseTimeout);
}
catch (AuthenticationTimeoutException e)
{
// return basic auth challenge
return false;
}
}
else if (isAlwaysAllowBasicAuthForWebScriptsHome())
{
boolean shouldUseTimeout = shouldUseTimeoutForAdminAccessingWebScriptsHome(required, isGuest);
if (shouldUseTimeout && isBasicAuthHeaderPresentForAdmin())
{
return callBasicAuthForAdminConsoleOrWebScriptsHomeAccess(required, isGuest);
}
try
{
userId = getRemoteUserWithTimeout(shouldUseTimeout);
}
catch (AuthenticationTimeoutException e)
{
@@ -252,38 +295,63 @@ public class RemoteUserAuthenticatorFactory extends BasicHttpAuthenticatorFactor
authenticated = super.authenticate(required, isGuest);
}
}
if (!authenticated && servletReq.getServiceMatch() != null &&
isAdminConsoleWebScript(servletReq.getServiceMatch().getWebScript()) && isAdminConsoleAuthenticatorActive())
if (!authenticated && servletReq.getServiceMatch() != null)
{
adminConsoleAuthenticator.requestAuthentication(this.servletReq.getHttpServletRequest(), this.servletRes.getHttpServletResponse());
WebScript webScript = servletReq.getServiceMatch().getWebScript();
if (isAdminConsole(webScript) && isAdminConsoleAuthenticatorActive())
{
adminConsoleAuthenticator.requestAuthentication(
this.servletReq.getHttpServletRequest(),
this.servletRes.getHttpServletResponse());
}
else if (isWebScriptsHome(webScript)
&& isWebScriptsHomeAuthenticatorActive())
{
webScriptsHomeAuthenticator.requestAuthentication(
this.servletReq.getHttpServletRequest(),
this.servletRes.getHttpServletResponse());
}
}
return authenticated;
}
private boolean callBasicAuthForAdminConsoleAccess(RequiredAuthentication required, boolean isGuest)
private boolean callBasicAuthForAdminConsoleOrWebScriptsHomeAccess(RequiredAuthentication required, boolean isGuest)
{
// return REST call, after a timeout/basic auth challenge
if (LOGGER.isTraceEnabled())
{
LOGGER.trace("An Admin Console request has come in with Basic Auth headers present for an admin user.");
LOGGER.trace("An Admin Console or WebScripts Home request has come in with Basic Auth headers present for an admin user.");
}
// In order to prompt for another password, in case it was not entered correctly,
// the output of this method should be returned by the calling "authenticate" method;
// This would also mean, that once the admin basic auth header is present,
// the authentication chain will not be used for the admin console access
// the authentication chain will not be used for access
return super.authenticate(required, isGuest);
}
private boolean shouldUseTimeoutForAdminAccessingAdminConsole(RequiredAuthentication required, boolean isGuest)
{
boolean useTimeoutForAdminAccessingAdminConsole = RequiredAuthentication.admin.equals(required) && !isGuest &&
servletReq.getServiceMatch() != null && isAdminConsoleWebScript(servletReq.getServiceMatch().getWebScript());
boolean adminConsoleTimeout = RequiredAuthentication.admin.equals(required) && !isGuest &&
servletReq.getServiceMatch() != null && isAdminConsole(servletReq.getServiceMatch().getWebScript());
if (LOGGER.isTraceEnabled())
{
LOGGER.trace("Should ensure that the admins can login with basic auth: " + useTimeoutForAdminAccessingAdminConsole);
LOGGER.trace("Should ensure that the admins can login with basic auth: " + adminConsoleTimeout);
}
return useTimeoutForAdminAccessingAdminConsole;
return adminConsoleTimeout;
}
private boolean shouldUseTimeoutForAdminAccessingWebScriptsHome(RequiredAuthentication required, boolean isGuest)
{
boolean adminWebScriptsHomeTimeout = RequiredAuthentication.admin.equals(required) && !isGuest &&
servletReq.getServiceMatch() != null && isWebScriptsHome(servletReq.getServiceMatch().getWebScript());
if (LOGGER.isTraceEnabled())
{
LOGGER.trace("Should ensure that the admins can login with basic auth: " + adminWebScriptsHomeTimeout);
}
return adminWebScriptsHomeTimeout;
}
private boolean isRemoteUserMapperActive()
@@ -296,7 +364,12 @@ public class RemoteUserAuthenticatorFactory extends BasicHttpAuthenticatorFactor
return adminConsoleAuthenticator != null && (!(adminConsoleAuthenticator instanceof ActivateableBean) || ((ActivateableBean) adminConsoleAuthenticator).isActive());
}
protected boolean isAdminConsoleWebScript(WebScript webScript)
private boolean isWebScriptsHomeAuthenticatorActive()
{
return webScriptsHomeAuthenticator != null && (!(webScriptsHomeAuthenticator instanceof ActivateableBean) || ((ActivateableBean) webScriptsHomeAuthenticator).isActive());
}
protected boolean isAdminConsole(WebScript webScript)
{
if (webScript == null || adminConsoleScriptFamilies == null || webScript.getDescription() == null
|| webScript.getDescription().getFamilys() == null)
@@ -310,7 +383,7 @@ public class RemoteUserAuthenticatorFactory extends BasicHttpAuthenticatorFactor
}
// intersect the "family" sets defined
Set<String> families = new HashSet<String>(webScript.getDescription().getFamilys());
Set<String> families = new HashSet<>(webScript.getDescription().getFamilys());
families.retainAll(adminConsoleScriptFamilies);
final boolean isAdminConsole = !families.isEmpty();
@@ -322,6 +395,23 @@ public class RemoteUserAuthenticatorFactory extends BasicHttpAuthenticatorFactor
return isAdminConsole;
}
protected boolean isWebScriptsHome(WebScript webScript)
{
if (webScript == null || webScript.toString() == null)
{
return false;
}
boolean isWebScriptsHome = webScript.toString().startsWith(WEB_SCRIPTS_BASE_PATH);
if (LOGGER.isTraceEnabled() && isWebScriptsHome)
{
LOGGER.trace("Detected a WebScripts Home webscript: " + webScript);
}
return isWebScriptsHome;
}
protected String getRemoteUserWithTimeout(boolean useTimeout) throws AuthenticationTimeoutException
{
if (!useTimeout)
@@ -417,7 +507,21 @@ public class RemoteUserAuthenticatorFactory extends BasicHttpAuthenticatorFactor
if (isRemoteUserMapperActive())
{
userId = adminConsoleAuthenticator.getAdminConsoleUser(this.servletReq.getHttpServletRequest(), this.servletRes.getHttpServletResponse());
userId = adminConsoleAuthenticator.getUserId(this.servletReq.getHttpServletRequest(), this.servletRes.getHttpServletResponse());
}
logRemoteUserID(userId);
return userId;
}
protected String getWebScriptsHomeUser()
{
String userId = null;
if (isRemoteUserMapperActive())
{
userId = webScriptsHomeAuthenticator.getUserId(this.servletReq.getHttpServletRequest(), this.servletRes.getHttpServletResponse());
}
logRemoteUserID(userId);

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 Alfresco Software Limited
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -75,6 +75,7 @@ public class ActionNodeParameterValidator implements ActionValidator
static final String NO_PROPER_PERMISSIONS_FOR_NODE = "No proper permissions for node: ";
static final String NOT_A_CATEGORY = "Node is not a category ";
static final String NOT_A_FOLDER = "Node is not a folder ";
static final String NO_LONGER_EXISTS = "%s having Id: %s no longer exists. Please update your rule definition.";
private final Actions actions;
private final NamespaceService namespaceService;
@@ -132,7 +133,15 @@ public class ActionNodeParameterValidator implements ActionValidator
.filter(pd -> action.getParams().containsKey(pd.getName()))
.forEach(p -> {
final String nodeId = Objects.toString(action.getParams().get(p.getName()), Strings.EMPTY);
final NodeRef nodeRef = nodes.validateNode(nodeId);
NodeRef nodeRef;
try
{
nodeRef = nodes.validateNode(nodeId);
}
catch (EntityNotFoundException e)
{
throw new EntityNotFoundException(String.format(NO_LONGER_EXISTS, p.getDisplayLabel(), nodeId), e);
}
validatePermission(action.getActionDefinitionId(), p.getName(), nodeRef);
validateType(action.getActionDefinitionId(), nodeRef);
});
@@ -169,4 +178,5 @@ public class ActionNodeParameterValidator implements ActionValidator
throw new InvalidArgumentException(NOT_A_CATEGORY + nodeRef.getId());
}
}
}

View File

@@ -5,4 +5,4 @@
<authentication>guest</authentication>
<transaction allow="readonly">required</transaction>
<lifecycle>internal</lifecycle>
</webscript>
</webscript>

View File

@@ -40,7 +40,6 @@
"items":
[
<#list results as row>
<#if row.item.hasPermission("Read")>
{
"type": "${row.item.typeShort}",
"parentType": "${row.item.parentTypeShort!""}",
@@ -76,7 +75,6 @@
"nodeRef": "${row.item.nodeRef}"<#if row.selectable?exists>,
"selectable" : ${row.selectable?string}</#if>
}<#if row_has_next>,</#if>
</#if>
</#list>
]
}

View File

@@ -214,9 +214,13 @@
<property name="authenticationListener" ref="webScriptAuthenticationListener"/>
<property name="remoteUserMapper" ref="RemoteUserMapper" />
<property name="adminConsoleAuthenticator" ref="AdminConsoleAuthenticator" />
<property name="webScriptsHomeAuthenticator" ref="WebScriptsHomeAuthenticator" />
<property name="alwaysAllowBasicAuthForAdminConsole">
<value>${authentication.alwaysAllowBasicAuthForAdminConsole.enabled}</value>
</property>
<property name="alwaysAllowBasicAuthForWebScriptsHome">
<value>${authentication.alwaysAllowBasicAuthForWebScriptsHome.enabled}</value>
</property>
<property name="getRemoteUserTimeoutMilliseconds">
<value>${authentication.getRemoteUserTimeoutMilliseconds}</value>
</property>

View File

@@ -29,6 +29,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -203,8 +204,8 @@ public class MoveMethodTest
@Test
public void canRenameFoldersWhenNewNameMatchesShufflePattern() throws Exception
{
when(davHelper.isRenameShuffle(destPath)).thenReturn(true);
when(davHelper.isRenameShuffle(sourcePath)).thenReturn(false);
lenient().when(davHelper.isRenameShuffle(destPath)).thenReturn(true);
lenient().when(davHelper.isRenameShuffle(sourcePath)).thenReturn(false);
// Test: Perform the rename
moveMethod.moveOrCopy(sourceNodeRef, sourceParentNodeRef, destParentNodeRef, "dest.doc");
@@ -247,8 +248,8 @@ public class MoveMethodTest
sourcePath = "/path/from/test.doc";
moveMethod.m_strPath = sourcePath;
when(davHelper.getServiceRegistry()).thenReturn(mockServiceRegistry);
when(mockServiceRegistry.getContentService()).thenReturn(mockContentService);
lenient().when(davHelper.getServiceRegistry()).thenReturn(mockServiceRegistry);
lenient().when(mockServiceRegistry.getContentService()).thenReturn(mockContentService);
List<String> sourcePathSplit = Arrays.asList("path", "from", "test.doc");
when(davHelper.splitAllPaths(sourcePath)).thenReturn(sourcePathSplit);
@@ -366,7 +367,7 @@ public class MoveMethodTest
when(mockFileFolderService.resolveNamePath(rootNode, sourcePathSplit)).thenReturn(tmpFI);
when(davHelper.isRenameShuffle(destPath)).thenReturn(false);
when(davHelper.isRenameShuffle(sourcePath)).thenReturn(true);
lenient().when(davHelper.isRenameShuffle(sourcePath)).thenReturn(true);
moveMethod.moveOrCopy(atmpFI.getNodeRef(), companyHomeNodeRef, companyHomeNodeRef, bakFileName);

View File

@@ -1 +0,0 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.2.0.35</version>
<version>25.2.0.46</version>
</parent>
<dependencies>
@@ -627,11 +627,6 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>

View File

@@ -31,12 +31,12 @@ import jakarta.servlet.http.HttpServletResponse;
import org.alfresco.repo.management.subsystems.ActivateableBean;
/**
* A default {@link AdminConsoleAuthenticator} implementation. Returns null to request a basic auth challenge.
* A default {@link ExternalUserAuthenticator} implementation. Returns null to request a basic auth challenge.
*/
public class DefaultAdminConsoleAuthenticator implements AdminConsoleAuthenticator, ActivateableBean
public class DefaultAdminConsoleAuthenticator implements ExternalUserAuthenticator, ActivateableBean
{
@Override
public String getAdminConsoleUser(HttpServletRequest request, HttpServletResponse response)
public String getUserId(HttpServletRequest request, HttpServletResponse response)
{
return null;
}

View File

@@ -0,0 +1,55 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.security.authentication.external;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.alfresco.repo.management.subsystems.ActivateableBean;
/**
* A default {@link ExternalUserAuthenticator} implementation. Returns null to request a basic auth challenge.
*/
public class DefaultWebScriptsHomeAuthenticator implements ExternalUserAuthenticator, ActivateableBean
{
@Override
public String getUserId(HttpServletRequest request, HttpServletResponse response)
{
return null;
}
@Override
public void requestAuthentication(HttpServletRequest request, HttpServletResponse response)
{
// No implementation
}
@Override
public boolean isActive()
{
return false;
}
}

View File

@@ -29,28 +29,17 @@ import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
/**
* An interface for objects capable of extracting an externally authenticated user ID from the HTTP Admin Console webscript request.
* An interface for objects capable of extracting an externally authenticated user ID from the HTTP request.
*/
public interface AdminConsoleAuthenticator
public interface ExternalUserAuthenticator
{
/**
* Gets an externally authenticated user ID from the HTTP Admin Console webscript request.
*
* @param request
* the request
* @param response
* the response
* Gets an externally authenticated user ID from the HTTP request.
*
* @return the user ID or <code>null</code> if the user is unauthenticated
*/
String getAdminConsoleUser(HttpServletRequest request, HttpServletResponse response);
String getUserId(HttpServletRequest request, HttpServletResponse response);
/**
* Requests an authentication.
*
* @param request
* the request
* @param response
* the response
*/
/* Sends redirect to external site to initiate the OIDC authorization code flow. */
void requestAuthentication(HttpServletRequest request, HttpServletResponse response);
}

View File

@@ -76,6 +76,18 @@ public class IdentityServiceConfig
private String lastNameAttribute;
private String emailAttribute;
private long jwtClockSkewMs;
private String webScriptsHomeRedirectPath;
private String webScriptsHomeScopes;
public String getWebScriptsHomeRedirectPath()
{
return webScriptsHomeRedirectPath;
}
public void setWebScriptsHomeRedirectPath(String webScriptsHomeRedirectPath)
{
this.webScriptsHomeRedirectPath = webScriptsHomeRedirectPath;
}
/**
*
@@ -359,6 +371,18 @@ public class IdentityServiceConfig
this.adminConsoleScopes = adminConsoleScopes;
}
public Set<String> getWebScriptsHomeScopes()
{
return Stream.of(webScriptsHomeScopes.split(","))
.map(String::trim)
.collect(Collectors.toUnmodifiableSet());
}
public void setWebScriptsHomeScopes(String webScriptsHomeScopes)
{
this.webScriptsHomeScopes = webScriptsHomeScopes;
}
public Set<String> getPasswordGrantScopes()
{
return Stream.of(passwordGrantScopes.split(","))

View File

@@ -23,7 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.security.authentication.identityservice.admin;
package org.alfresco.repo.security.authentication.identityservice.authentication;
import static org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacade.AuthorizationGrant.authorizationCode;
import static org.alfresco.repo.security.authentication.identityservice.IdentityServiceMetadataKey.SCOPES_SUPPORTED;
@@ -32,7 +32,6 @@ import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
@@ -50,9 +49,8 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio
import org.springframework.security.oauth2.client.registration.ClientRegistration.ProviderDetails;
import org.springframework.web.util.UriComponentsBuilder;
import org.alfresco.repo.management.subsystems.ActivateableBean;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.repo.security.authentication.external.AdminConsoleAuthenticator;
import org.alfresco.repo.security.authentication.external.ExternalUserAuthenticator;
import org.alfresco.repo.security.authentication.external.RemoteUserMapper;
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceConfig;
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacade;
@@ -60,27 +58,26 @@ import org.alfresco.repo.security.authentication.identityservice.IdentityService
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacade.AuthorizationException;
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacade.AuthorizationGrant;
/**
* An {@link AdminConsoleAuthenticator} implementation to extract an externally authenticated user ID or to initiate the OIDC authorization code flow.
*/
public class IdentityServiceAdminConsoleAuthenticator implements AdminConsoleAuthenticator, ActivateableBean
public abstract class AbstractIdentityServiceAuthenticator implements ExternalUserAuthenticator
{
private static final Logger LOGGER = LoggerFactory.getLogger(IdentityServiceAdminConsoleAuthenticator.class);
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractIdentityServiceAuthenticator.class);
private static final String ALFRESCO_ACCESS_TOKEN = "ALFRESCO_ACCESS_TOKEN";
private static final String ALFRESCO_REFRESH_TOKEN = "ALFRESCO_REFRESH_TOKEN";
private static final String ALFRESCO_TOKEN_EXPIRATION = "ALFRESCO_TOKEN_EXPIRATION";
private IdentityServiceConfig identityServiceConfig;
private IdentityServiceFacade identityServiceFacade;
private AdminConsoleAuthenticationCookiesService cookiesService;
private RemoteUserMapper remoteUserMapper;
private boolean isEnabled;
protected IdentityServiceConfig identityServiceConfig;
protected IdentityServiceFacade identityServiceFacade;
protected AdminAuthenticationCookiesService cookiesService;
protected RemoteUserMapper remoteUserMapper;
protected abstract String getConfiguredRedirectPath();
protected abstract Set<String> getConfiguredScopes();
@Override
public String getAdminConsoleUser(HttpServletRequest request, HttpServletResponse response)
public String getUserId(HttpServletRequest request, HttpServletResponse response)
{
// Try to extract username from the authorization header
String username = remoteUserMapper.getRemoteUser(request);
if (username != null)
{
@@ -107,16 +104,12 @@ public class IdentityServiceAdminConsoleAuthenticator implements AdminConsoleAut
return null;
}
return remoteUserMapper.getRemoteUser(decorateBearerHeader(bearerToken, request));
HttpServletRequest wrappedRequest = newRequestWrapper(Map.of("Authorization", "Bearer " + bearerToken), request);
return remoteUserMapper.getRemoteUser(wrappedRequest);
}
@Override
public void requestAuthentication(HttpServletRequest request, HttpServletResponse response)
{
respondWithAuthChallenge(request, response);
}
private void respondWithAuthChallenge(HttpServletRequest request, HttpServletResponse response)
{
try
{
@@ -124,7 +117,8 @@ public class IdentityServiceAdminConsoleAuthenticator implements AdminConsoleAut
{
LOGGER.debug("Responding with the authentication challenge");
}
response.sendRedirect(getAuthenticationRequest(request));
String authenticationRequest = buildAuthRequestUrl(request);
response.sendRedirect(authenticationRequest);
}
catch (IOException e)
{
@@ -133,84 +127,34 @@ public class IdentityServiceAdminConsoleAuthenticator implements AdminConsoleAut
}
}
private String retrieveTokenUsingAuthCode(HttpServletRequest request, HttpServletResponse response, String code)
protected String getRedirectUri(String requestURL)
{
String bearerToken = null;
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("Retrieving a response using the Authorization Code at the Token Endpoint");
}
try
{
AccessTokenAuthorization accessTokenAuthorization = identityServiceFacade.authorize(
authorizationCode(code, request.getRequestURL().toString()));
addCookies(response, accessTokenAuthorization);
bearerToken = accessTokenAuthorization.getAccessToken().getTokenValue();
}
catch (AuthorizationException exception)
{
if (LOGGER.isWarnEnabled())
{
LOGGER.warn(
"Error while trying to retrieve a response using the Authorization Code at the Token Endpoint: {}",
exception.getMessage());
}
}
return bearerToken;
return buildRedirectUri(requestURL, getConfiguredRedirectPath());
}
private String refreshTokenIfNeeded(HttpServletRequest request, HttpServletResponse response, String bearerToken)
{
String refreshToken = cookiesService.getCookie(ALFRESCO_REFRESH_TOKEN, request);
String authTokenExpiration = cookiesService.getCookie(ALFRESCO_TOKEN_EXPIRATION, request);
try
{
if (isAuthTokenExpired(authTokenExpiration))
{
bearerToken = refreshAuthToken(refreshToken, response);
}
}
catch (Exception e)
{
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("Error while trying to refresh Auth Token: {}", e.getMessage());
}
bearerToken = null;
resetCookies(response);
}
return bearerToken;
}
private void addCookies(HttpServletResponse response, AccessTokenAuthorization accessTokenAuthorization)
{
cookiesService.addCookie(ALFRESCO_ACCESS_TOKEN, accessTokenAuthorization.getAccessToken().getTokenValue(), response);
cookiesService.addCookie(ALFRESCO_TOKEN_EXPIRATION, String.valueOf(
accessTokenAuthorization.getAccessToken().getExpiresAt().toEpochMilli()), response);
cookiesService.addCookie(ALFRESCO_REFRESH_TOKEN, accessTokenAuthorization.getRefreshTokenValue(), response);
}
private String getAuthenticationRequest(HttpServletRequest request)
public String buildAuthRequestUrl(HttpServletRequest request)
{
ClientRegistration clientRegistration = identityServiceFacade.getClientRegistration();
State state = new State();
UriComponentsBuilder authRequestBuilder = UriComponentsBuilder.fromUriString(clientRegistration.getProviderDetails().getAuthorizationUri())
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(clientRegistration.getProviderDetails()
.getAuthorizationUri())
.queryParam("client_id", clientRegistration.getClientId())
.queryParam("redirect_uri", getRedirectUri(request.getRequestURL().toString()))
.queryParam("response_type", "code")
.queryParam("scope", String.join("+", getScopes(clientRegistration)))
.queryParam("scope", String.join("+", getConfiguredScopes(clientRegistration)))
.queryParam("state", state.toString());
if (StringUtils.isNotBlank(identityServiceConfig.getAudience()))
{
authRequestBuilder.queryParam("audience", identityServiceConfig.getAudience());
builder.queryParam("audience", identityServiceConfig.getAudience());
}
return authRequestBuilder.build().toUriString();
return builder.build()
.toUriString();
}
private Set<String> getScopes(ClientRegistration clientRegistration)
private Set<String> getConfiguredScopes(ClientRegistration clientRegistration)
{
return Optional.ofNullable(clientRegistration.getProviderDetails())
.map(ProviderDetails::getConfigurationMetadata)
@@ -223,100 +167,149 @@ public class IdentityServiceAdminConsoleAuthenticator implements AdminConsoleAut
private Set<String> getSupportedScopes(Scope scopes)
{
Set<String> configuredScopes = getConfiguredScopes();
return scopes.stream()
.filter(this::hasAdminConsoleScope)
.map(Identifier::getValue)
.filter(configuredScopes::contains)
.collect(Collectors.toSet());
}
private boolean hasAdminConsoleScope(Scope.Value scope)
{
return identityServiceConfig.getAdminConsoleScopes().contains(scope.getValue());
}
private String getRedirectUri(String requestURL)
protected String buildRedirectUri(String requestURL, String overridePath)
{
try
{
URI originalUri = new URI(requestURL);
URI redirectUri = new URI(originalUri.getScheme(), originalUri.getAuthority(), identityServiceConfig.getAdminConsoleRedirectPath(), originalUri.getQuery(), originalUri.getFragment());
String path = overridePath != null ? overridePath : originalUri.getPath();
URI redirectUri = new URI(
originalUri.getScheme(),
originalUri.getAuthority(),
path,
originalUri.getQuery(),
originalUri.getFragment());
return redirectUri.toASCIIString();
}
catch (URISyntaxException e)
{
LOGGER.error("Error while trying to get the redirect URI and respond with the authentication challenge: {}", e.getMessage(), e);
LOGGER.error("Redirect URI construction failed: {}", e.getMessage(), e);
throw new AuthenticationException(e.getMessage(), e);
}
}
private void resetCookies(HttpServletResponse response)
public void challenge(HttpServletRequest request, HttpServletResponse response)
{
try
{
response.sendRedirect(buildAuthRequestUrl(request));
}
catch (IOException e)
{
throw new AuthenticationException("Auth redirect failed", e);
}
}
protected String retrieveTokenUsingAuthCode(HttpServletRequest request, HttpServletResponse response, String code)
{
try
{
AccessTokenAuthorization accessTokenAuthorization = identityServiceFacade.authorize(authorizationCode(code, getRedirectUri(request.getRequestURL()
.toString())));
addCookies(response, accessTokenAuthorization);
return accessTokenAuthorization.getAccessToken()
.getTokenValue();
}
catch (AuthorizationException exception)
{
LOGGER.warn("Error while trying to retrieve token using Authorization Code: {}", exception.getMessage());
return null;
}
}
protected String refreshTokenIfNeeded(HttpServletRequest request, HttpServletResponse response, String bearerToken)
{
String refreshToken = cookiesService.getCookie(ALFRESCO_REFRESH_TOKEN, request);
String authTokenExpiration = cookiesService.getCookie(ALFRESCO_TOKEN_EXPIRATION, request);
try
{
if (isAuthTokenExpired(authTokenExpiration))
{
bearerToken = refreshAuthToken(refreshToken, response);
}
}
catch (Exception e)
{
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("Token refresh failed: {}", e.getMessage());
}
bearerToken = null;
resetCookies(response);
}
return bearerToken;
}
private static boolean isAuthTokenExpired(String authTokenExpiration)
{
return authTokenExpiration == null || Instant.now()
.compareTo(Instant.ofEpochMilli(Long.parseLong(authTokenExpiration))) >= 0;
}
private String refreshAuthToken(String refreshToken, HttpServletResponse response)
{
AccessTokenAuthorization accessTokenAuthorization = identityServiceFacade.authorize(AuthorizationGrant.refreshToken(refreshToken));
if (accessTokenAuthorization == null || accessTokenAuthorization.getAccessToken() == null)
{
throw new AuthenticationException("Refresh token response is invalid.");
}
addCookies(response, accessTokenAuthorization);
return accessTokenAuthorization.getAccessToken()
.getTokenValue();
}
protected void addCookies(HttpServletResponse response, AccessTokenAuthorization accessTokenAuthorization)
{
cookiesService.addCookie(ALFRESCO_ACCESS_TOKEN, accessTokenAuthorization.getAccessToken()
.getTokenValue(), response);
cookiesService.addCookie(ALFRESCO_TOKEN_EXPIRATION, String.valueOf(accessTokenAuthorization.getAccessToken()
.getExpiresAt()
.toEpochMilli()), response);
cookiesService.addCookie(ALFRESCO_REFRESH_TOKEN, accessTokenAuthorization.getRefreshTokenValue(), response);
}
protected void resetCookies(HttpServletResponse response)
{
cookiesService.resetCookie(ALFRESCO_TOKEN_EXPIRATION, response);
cookiesService.resetCookie(ALFRESCO_ACCESS_TOKEN, response);
cookiesService.resetCookie(ALFRESCO_REFRESH_TOKEN, response);
}
private String refreshAuthToken(String refreshToken, HttpServletResponse response)
protected HttpServletRequest newRequestWrapper(Map<String, String> headers, HttpServletRequest request)
{
AccessTokenAuthorization accessTokenAuthorization = doRefreshAuthToken(refreshToken);
addCookies(response, accessTokenAuthorization);
return accessTokenAuthorization.getAccessToken().getTokenValue();
return new AdditionalHeadersHttpServletRequestWrapper(headers, request);
}
private AccessTokenAuthorization doRefreshAuthToken(String refreshToken)
// Setters
public void setIdentityServiceConfig(IdentityServiceConfig config)
{
AccessTokenAuthorization accessTokenAuthorization = identityServiceFacade.authorize(
AuthorizationGrant.refreshToken(refreshToken));
if (accessTokenAuthorization == null || accessTokenAuthorization.getAccessToken() == null)
{
throw new AuthenticationException("AccessTokenResponse is null or empty");
}
return accessTokenAuthorization;
this.identityServiceConfig = config;
}
private static boolean isAuthTokenExpired(String authTokenExpiration)
public void setIdentityServiceFacade(IdentityServiceFacade facade)
{
return Instant.now().compareTo(Instant.ofEpochMilli(Long.parseLong(authTokenExpiration))) >= 0;
this.identityServiceFacade = facade;
}
private HttpServletRequest decorateBearerHeader(String authToken, HttpServletRequest servletRequest)
public void setCookiesService(AdminAuthenticationCookiesService service)
{
Map<String, String> additionalHeaders = new HashMap<>();
additionalHeaders.put("Authorization", "Bearer " + authToken);
return new AdminConsoleHttpServletRequestWrapper(additionalHeaders, servletRequest);
this.cookiesService = service;
}
public void setIdentityServiceFacade(
IdentityServiceFacade identityServiceFacade)
public void setRemoteUserMapper(RemoteUserMapper mapper)
{
this.identityServiceFacade = identityServiceFacade;
}
public void setRemoteUserMapper(RemoteUserMapper remoteUserMapper)
{
this.remoteUserMapper = remoteUserMapper;
}
public void setCookiesService(
AdminConsoleAuthenticationCookiesService cookiesService)
{
this.cookiesService = cookiesService;
}
public void setIdentityServiceConfig(
IdentityServiceConfig identityServiceConfig)
{
this.identityServiceConfig = identityServiceConfig;
}
@Override
public boolean isActive()
{
return this.isEnabled;
}
public void setActive(boolean isEnabled)
{
this.isEnabled = isEnabled;
this.remoteUserMapper = mapper;
}
}

View File

@@ -23,7 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.security.authentication.identityservice.admin;
package org.alfresco.repo.security.authentication.identityservice.authentication;
import static java.util.Arrays.asList;
import static java.util.Collections.enumeration;
@@ -37,20 +37,12 @@ import jakarta.servlet.http.HttpServletRequestWrapper;
import org.alfresco.util.PropertyCheck;
public class AdminConsoleHttpServletRequestWrapper extends HttpServletRequestWrapper
public class AdditionalHeadersHttpServletRequestWrapper extends HttpServletRequestWrapper
{
private final Map<String, String> additionalHeaders;
private final HttpServletRequest wrappedRequest;
/**
* Constructs a request object wrapping the given request.
*
* @param request
* the request to wrap
* @throws IllegalArgumentException
* if the request is null
*/
public AdminConsoleHttpServletRequestWrapper(Map<String, String> additionalHeaders, HttpServletRequest request)
public AdditionalHeadersHttpServletRequestWrapper(Map<String, String> additionalHeaders, HttpServletRequest request)
{
super(request);
PropertyCheck.mandatory(this, "additionalHeaders", additionalHeaders);

View File

@@ -23,7 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.security.authentication.identityservice.admin;
package org.alfresco.repo.security.authentication.identityservice.authentication;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
@@ -34,12 +34,12 @@ import org.alfresco.repo.admin.SysAdminParams;
/**
* Service to handle Admin Console authentication-related cookies.
*/
public class AdminConsoleAuthenticationCookiesService
public class AdminAuthenticationCookiesService
{
private final SysAdminParams sysAdminParams;
private final int cookieLifetime;
public AdminConsoleAuthenticationCookiesService(SysAdminParams sysAdminParams, int cookieLifetime)
public AdminAuthenticationCookiesService(SysAdminParams sysAdminParams, int cookieLifetime)
{
this.sysAdminParams = sysAdminParams;
this.cookieLifetime = cookieLifetime;

View File

@@ -0,0 +1,64 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.security.authentication.identityservice.authentication.admin;
import java.util.Set;
import org.alfresco.repo.management.subsystems.ActivateableBean;
import org.alfresco.repo.security.authentication.external.ExternalUserAuthenticator;
import org.alfresco.repo.security.authentication.identityservice.authentication.AbstractIdentityServiceAuthenticator;
/**
* An {@link ExternalUserAuthenticator} implementation to extract an externally authenticated user ID or to initiate the OIDC authorization code flow.
*/
public class IdentityServiceAdminConsoleAuthenticator extends AbstractIdentityServiceAuthenticator
implements ExternalUserAuthenticator, ActivateableBean
{
private boolean isEnabled;
@Override
protected Set<String> getConfiguredScopes()
{
return identityServiceConfig.getAdminConsoleScopes();
}
@Override
protected String getConfiguredRedirectPath()
{
return identityServiceConfig.getAdminConsoleRedirectPath();
}
@Override
public boolean isActive()
{
return isEnabled;
}
public void setActive(boolean isEnabled)
{
this.isEnabled = isEnabled;
}
}

View File

@@ -0,0 +1,64 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.security.authentication.identityservice.authentication.webscripts;
import java.util.Set;
import org.alfresco.repo.management.subsystems.ActivateableBean;
import org.alfresco.repo.security.authentication.external.ExternalUserAuthenticator;
import org.alfresco.repo.security.authentication.identityservice.authentication.AbstractIdentityServiceAuthenticator;
/**
* An {@link ExternalUserAuthenticator} implementation to extract an externally authenticated user ID or to initiate the OIDC authorization code flow.
*/
public class IdentityServiceWebScriptsHomeAuthenticator extends AbstractIdentityServiceAuthenticator
implements ExternalUserAuthenticator, ActivateableBean
{
private boolean isEnabled;
@Override
protected String getConfiguredRedirectPath()
{
return identityServiceConfig.getWebScriptsHomeRedirectPath();
}
@Override
protected Set<String> getConfiguredScopes()
{
return identityServiceConfig.getWebScriptsHomeScopes();
}
@Override
public boolean isActive()
{
return this.isEnabled;
}
public void setActive(boolean isEnabled)
{
this.isEnabled = isEnabled;
}
}

View File

@@ -914,7 +914,7 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
String[] tokenizedFilter = SearchLanguageConversion.tokenizeString(escNameFilter);
// cm:name
query.append(" cm:name:\" ");
query.append(" cm:name:\"");
for (int i = 0; i < tokenizedFilter.length; i++)
{
if (i != 0) // Not first element

View File

@@ -135,7 +135,7 @@
</property>
<property name="interfaces">
<list>
<value>org.alfresco.repo.security.authentication.external.AdminConsoleAuthenticator</value>
<value>org.alfresco.repo.security.authentication.external.ExternalUserAuthenticator</value>
<value>org.alfresco.repo.management.subsystems.ActivateableBean</value>
</list>
</property>
@@ -144,6 +144,22 @@
</property>
</bean>
<bean id="WebScriptsHomeAuthenticator"
class="org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory">
<property name="applicationContextManager">
<ref bean="Authentication" />
</property>
<property name="interfaces">
<list>
<value>org.alfresco.repo.security.authentication.external.ExternalUserAuthenticator</value>
<value>org.alfresco.repo.management.subsystems.ActivateableBean</value>
</list>
</property>
<property name="sourceBeanName">
<value>webScriptsHomeAuthenticator</value>
</property>
</bean>
<!-- Passwords are encoded using MD4 -->
<!-- This is not ideal and only done to be compatible with NTLM -->
<!-- authentication against the default authentication mechanism. -->

View File

@@ -563,6 +563,7 @@ authentication.ticket.validDuration=PT1H
authentication.ticket.useSingleTicketPerUser=true
authentication.alwaysAllowBasicAuthForAdminConsole.enabled=true
authentication.alwaysAllowBasicAuthForWebScriptsHome.enabled=true
authentication.getRemoteUserTimeoutMilliseconds=10000
# FTP access

View File

@@ -104,4 +104,7 @@
<ref bean="transactionService" />
</property>
</bean>
</beans>
<bean id="webScriptsHomeAuthenticator" class="org.alfresco.repo.security.authentication.external.DefaultWebScriptsHomeAuthenticator" />
</beans>

View File

@@ -170,6 +170,9 @@
<property name="adminConsoleScopes">
<value>${identity-service.admin-console.scopes:openid,profile,email,offline_access}</value>
</property>
<property name="webScriptsHomeScopes">
<value>${identity-service.webscripts-home.scopes:openid,profile,email,offline_access}</value>
</property>
<property name="passwordGrantScopes">
<value>${identity-service.password-grant.scopes:openid,profile,email}</value>
</property>
@@ -179,6 +182,9 @@
<property name="jwtClockSkewMs">
<value>${identity-service.jwt-clock-skew-ms:0}</value>
</property>
<property name="webScriptsHomeRedirectPath">
<value>${identity-service.webscripts-home.redirect-path}</value>
</property>
</bean>
<!-- Enable control over mapping between request and user ID -->
@@ -197,12 +203,12 @@
</property>
</bean>
<bean id="adminConsoleAuthenticationCookiesService" class="org.alfresco.repo.security.authentication.identityservice.admin.AdminConsoleAuthenticationCookiesService">
<constructor-arg ref="sysAdminParams" />
<constructor-arg value="${admin.console.cookie.lifetime:86400}" />
</bean>
<bean id="adminAuthenticationCookiesService" class="org.alfresco.repo.security.authentication.identityservice.authentication.AdminAuthenticationCookiesService">
<constructor-arg ref="sysAdminParams" />
<constructor-arg value="${admin.console.cookie.lifetime:86400}" />
</bean>
<bean id="adminConsoleAuthenticator" class="org.alfresco.repo.security.authentication.identityservice.admin.IdentityServiceAdminConsoleAuthenticator">
<bean id="adminConsoleAuthenticator" class="org.alfresco.repo.security.authentication.identityservice.authentication.admin.IdentityServiceAdminConsoleAuthenticator">
<property name="active">
<value>${identity-service.authentication.enabled}</value>
</property>
@@ -210,7 +216,7 @@
<ref bean="identityServiceFacade"/>
</property>
<property name="cookiesService">
<ref bean="adminConsoleAuthenticationCookiesService" />
<ref bean="adminAuthenticationCookiesService" />
</property>
<property name="remoteUserMapper">
<ref bean="remoteUserMapper" />
@@ -220,6 +226,24 @@
</property>
</bean>
<bean id="webScriptsHomeAuthenticator" class="org.alfresco.repo.security.authentication.identityservice.authentication.webscripts.IdentityServiceWebScriptsHomeAuthenticator">
<property name="active">
<value>${identity-service.authentication.enabled}</value>
</property>
<property name="identityServiceFacade">
<ref bean="identityServiceFacade"/>
</property>
<property name="cookiesService">
<ref bean="adminAuthenticationCookiesService" />
</property>
<property name="remoteUserMapper">
<ref bean="remoteUserMapper" />
</property>
<property name="identityServiceConfig">
<ref bean="identityServiceConfig" />
</property>
</bean>
<bean id="jitProvisioningHandler" class="org.alfresco.repo.security.authentication.identityservice.IdentityServiceJITProvisioningHandler">
<constructor-arg ref="PersonService"/>
<constructor-arg ref="identityServiceFacade"/>

View File

@@ -12,11 +12,13 @@ identity-service.resource=alfresco
identity-service.credentials.secret=
identity-service.public-client=true
identity-service.admin-console.redirect-path=/alfresco/s/admin/admin-communitysummary
identity-service.webscripts-home.redirect-path=/alfresco/s/index
identity-service.signature-algorithms=RS256,PS256
identity-service.first-name-attribute=given_name
identity-service.last-name-attribute=family_name
identity-service.email-attribute=email
identity-service.admin-console.scopes=openid,profile,email,offline_access
identity-service.webscripts-home.scopes=openid,profile,email,offline_access
identity-service.password-grant.scopes=openid,profile,email
identity-service.issuer-attribute=issuer
identity-service.jwt-clock-skew-ms=0

View File

@@ -34,11 +34,12 @@ import org.alfresco.repo.security.authentication.identityservice.IdentityService
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceJITProvisioningHandlerUnitTest;
import org.alfresco.repo.security.authentication.identityservice.LazyInstantiatingIdentityServiceFacadeUnitTest;
import org.alfresco.repo.security.authentication.identityservice.SpringBasedIdentityServiceFacadeUnitTest;
import org.alfresco.repo.security.authentication.identityservice.admin.AdminConsoleAuthenticationCookiesServiceUnitTest;
import org.alfresco.repo.security.authentication.identityservice.admin.AdminConsoleHttpServletRequestWrapperUnitTest;
import org.alfresco.repo.security.authentication.identityservice.admin.IdentityServiceAdminConsoleAuthenticatorUnitTest;
import org.alfresco.repo.security.authentication.identityservice.authentication.AdditionalHeadersHttpServletRequestWrapperUnitTest;
import org.alfresco.repo.security.authentication.identityservice.authentication.AdminAuthenticationCookiesServiceUnitTest;
import org.alfresco.repo.security.authentication.identityservice.authentication.admin.IdentityServiceAdminConsoleAuthenticatorUnitTest;
import org.alfresco.repo.security.authentication.identityservice.user.AccessTokenToDecodedTokenUserMapperUnitTest;
import org.alfresco.repo.security.authentication.identityservice.user.TokenUserToOIDCUserMapperUnitTest;
import org.alfresco.repo.security.authentication.identityservice.webscript.IdentityServiceWebScriptsHomeAuthenticatorUnitTest;
import org.alfresco.util.testing.category.DBTests;
import org.alfresco.util.testing.category.NonBuildTests;
@@ -153,9 +154,10 @@ import org.alfresco.util.testing.category.NonBuildTests;
IdentityServiceJITProvisioningHandlerUnitTest.class,
AccessTokenToDecodedTokenUserMapperUnitTest.class,
TokenUserToOIDCUserMapperUnitTest.class,
AdminConsoleAuthenticationCookiesServiceUnitTest.class,
AdminConsoleHttpServletRequestWrapperUnitTest.class,
AdminAuthenticationCookiesServiceUnitTest.class,
AdditionalHeadersHttpServletRequestWrapperUnitTest.class,
IdentityServiceAdminConsoleAuthenticatorUnitTest.class,
IdentityServiceWebScriptsHomeAuthenticatorUnitTest.class,
ClientRegistrationProviderUnitTest.class,
org.alfresco.repo.security.authentication.CompositePasswordEncoderTest.class,
org.alfresco.repo.security.authentication.PasswordHashingTest.class,

View File

@@ -46,12 +46,12 @@ import org.alfresco.util.test.junitrules.WellKnownNodes;
public class DataDictionaryFolderTest extends BaseSpringTest
{
@ClassRule
private static final ApplicationContextInit APP_CONTEXT_INIT = new ApplicationContextInit();
public static final ApplicationContextInit APP_CONTEXT_INIT = new ApplicationContextInit();
private static final String DATA_DICTIONARY = "Data Dictionary";
@Rule
private WellKnownNodes wellKnownNodes = new WellKnownNodes(APP_CONTEXT_INIT);
public WellKnownNodes wellKnownNodes = new WellKnownNodes(APP_CONTEXT_INIT);
private NodeService nodeService;

View File

@@ -31,7 +31,6 @@ import java.sql.Savepoint;
import java.util.Map;
import java.util.TreeMap;
import junit.framework.AssertionFailedError;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
@@ -61,7 +60,7 @@ public class EntityLookupCacheTest implements EntityLookupCallbackDAO<Long, Obje
private ControlDAO controlDAO;
@Before
protected void setUp() throws Exception
public void setUp() throws Exception
{
cache = new MemoryCache<Long, Object>();
entityLookupCacheA = new EntityLookupCache<Long, Object, String>(cache, "A", this);
@@ -72,18 +71,10 @@ public class EntityLookupCacheTest implements EntityLookupCallbackDAO<Long, Obje
Mockito.when(controlDAO.createSavepoint(Mockito.anyString())).thenReturn(Mockito.mock(Savepoint.class));
}
@Test
@Test(expected = AssertionError.class)
public void testLookupsUsingIncorrectValue() throws Exception
{
try
{
// Keep the "database" empty
entityLookupCacheA.getByValue(this);
}
catch (AssertionFailedError e)
{
// Expected
}
entityLookupCacheA.getByValue(this);
}
@Test

View File

@@ -37,6 +37,7 @@ import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.only;
@@ -161,7 +162,7 @@ public class CachingContentStoreTest
@Test
public void getReaderForItemMissingFromCacheButNoContentToCache()
{
when(cache.getReader("url")).thenThrow(new CacheMissException("url"));
lenient().when(cache.getReader("url")).thenThrow(new CacheMissException("url"));
when(backingStore.getReader("url")).thenReturn(sourceContent);
when(cache.put("url", sourceContent)).thenReturn(false);
@@ -305,9 +306,9 @@ public class CachingContentStoreTest
cachingStore.setQuota(quota);
// Don't veto writing the cache file.
when(quota.beforeWritingCacheFile(1274L)).thenReturn(true);
lenient().when(quota.beforeWritingCacheFile(1274L)).thenReturn(true);
// Do request cache file deletion.
when(quota.afterWritingCacheFile(1234L)).thenReturn(false);
lenient().when(quota.afterWritingCacheFile(1234L)).thenReturn(false);
ContentReader returnedReader = cachingStore.getReader("url");

View File

@@ -26,6 +26,7 @@
package org.alfresco.repo.lock;
import static org.junit.Assert.*;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.when;
import org.junit.Test;
@@ -53,8 +54,8 @@ public class LockUtilsTest
@Test
public void testIsLockedAndReadOnly_ForLockOwnerWithNullLockType()
{
when(lockService.getLockStatus(nodeRef)).thenReturn(LockStatus.LOCK_OWNER);
when(lockService.getLockType(nodeRef)).thenReturn(null);
lenient().when(lockService.getLockStatus(nodeRef)).thenReturn(LockStatus.LOCK_OWNER);
lenient().when(lockService.getLockType(nodeRef)).thenReturn(null);
when(lockService.isLockedAndReadOnly(nodeRef)).thenReturn(true);
boolean returnedVal = LockUtils.isLockedAndReadOnly(nodeRef, lockService);
@@ -64,8 +65,8 @@ public class LockUtilsTest
@Test
public void testIsLockedAndReadOnly_ForLockOwnerWithWriteLockType()
{
when(lockService.getLockStatus(nodeRef)).thenReturn(LockStatus.LOCK_OWNER);
when(lockService.getLockType(nodeRef)).thenReturn(LockType.WRITE_LOCK);
lenient().when(lockService.getLockStatus(nodeRef)).thenReturn(LockStatus.LOCK_OWNER);
lenient().when(lockService.getLockType(nodeRef)).thenReturn(LockType.WRITE_LOCK);
when(lockService.isLockedAndReadOnly(nodeRef)).thenReturn(false);
boolean returnedVal = LockUtils.isLockedAndReadOnly(nodeRef, lockService);
@@ -75,8 +76,8 @@ public class LockUtilsTest
@Test
public void testIsLockedAndReadOnly_ForLockOwnerWithNodeLockType()
{
when(lockService.getLockStatus(nodeRef)).thenReturn(LockStatus.LOCK_OWNER);
when(lockService.getLockType(nodeRef)).thenReturn(LockType.NODE_LOCK);
lenient().when(lockService.getLockStatus(nodeRef)).thenReturn(LockStatus.LOCK_OWNER);
lenient().when(lockService.getLockType(nodeRef)).thenReturn(LockType.NODE_LOCK);
when(lockService.isLockedAndReadOnly(nodeRef)).thenReturn(true);
boolean returnedVal = LockUtils.isLockedAndReadOnly(nodeRef, lockService);
@@ -86,8 +87,8 @@ public class LockUtilsTest
@Test
public void testIsLockedAndReadOnly_ForLockOwnerWithReadOnlyLockType()
{
when(lockService.getLockStatus(nodeRef)).thenReturn(LockStatus.LOCK_OWNER);
when(lockService.getLockType(nodeRef)).thenReturn(LockType.READ_ONLY_LOCK);
lenient().when(lockService.getLockStatus(nodeRef)).thenReturn(LockStatus.LOCK_OWNER);
lenient().when(lockService.getLockType(nodeRef)).thenReturn(LockType.READ_ONLY_LOCK);
when(lockService.isLockedAndReadOnly(nodeRef)).thenReturn(true);
boolean returnedVal = LockUtils.isLockedAndReadOnly(nodeRef, lockService);
@@ -97,7 +98,7 @@ public class LockUtilsTest
@Test
public void testIsLockedAndReadOnly_ForNoLock()
{
when(lockService.getLockStatus(nodeRef)).thenReturn(LockStatus.NO_LOCK);
lenient().when(lockService.getLockStatus(nodeRef)).thenReturn(LockStatus.NO_LOCK);
when(lockService.isLockedAndReadOnly(nodeRef)).thenReturn(false);
boolean returnedVal = LockUtils.isLockedAndReadOnly(nodeRef, lockService);
@@ -107,7 +108,7 @@ public class LockUtilsTest
@Test
public void testIsLockedAndReadOnly_ForExpiredLock()
{
when(lockService.getLockStatus(nodeRef)).thenReturn(LockStatus.LOCK_EXPIRED);
lenient().when(lockService.getLockStatus(nodeRef)).thenReturn(LockStatus.LOCK_EXPIRED);
when(lockService.isLockedAndReadOnly(nodeRef)).thenReturn(false);
boolean returnedVal = LockUtils.isLockedAndReadOnly(nodeRef, lockService);
@@ -117,7 +118,7 @@ public class LockUtilsTest
@Test
public void testIsLockedAndReadOnly_ForLock()
{
when(lockService.getLockStatus(nodeRef)).thenReturn(LockStatus.LOCKED);
lenient().when(lockService.getLockStatus(nodeRef)).thenReturn(LockStatus.LOCKED);
when(lockService.isLockedAndReadOnly(nodeRef)).thenReturn(true);
boolean returnedVal = LockUtils.isLockedAndReadOnly(nodeRef, lockService);

View File

@@ -23,7 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.security.authentication.identityservice.admin;
package org.alfresco.repo.security.authentication.identityservice.authentication;
import static java.util.Collections.enumeration;
import static java.util.Collections.list;
@@ -49,19 +49,18 @@ import org.mockito.Mock;
import org.alfresco.error.AlfrescoRuntimeException;
@SuppressWarnings("PMD.UseDiamondOperator")
public class AdminConsoleHttpServletRequestWrapperUnitTest
public class AdditionalHeadersHttpServletRequestWrapperUnitTest
{
private static final String DEFAULT_HEADER = "default_header";
private static final String DEFAULT_HEADER_VALUE = "default_value";
private static final String ADDITIONAL_HEADER = "additional_header";
private static final String ADDITIONAL_HEADER_VALUE = "additional_value";
private static final Map<String, String> DEFAULT_HEADERS = new HashMap<String, String>() {
private static final Map<String, String> DEFAULT_HEADERS = new HashMap<>() {
{
put(DEFAULT_HEADER, DEFAULT_HEADER_VALUE);
}
};
private static final Map<String, String> ADDITIONAL_HEADERS = new HashMap<String, String>() {
private static final Map<String, String> ADDITIONAL_HEADERS = new HashMap<>() {
{
put(ADDITIONAL_HEADER, ADDITIONAL_HEADER_VALUE);
}
@@ -69,25 +68,25 @@ public class AdminConsoleHttpServletRequestWrapperUnitTest
@Mock
private HttpServletRequest request;
private AdminConsoleHttpServletRequestWrapper requestWrapper;
private AdditionalHeadersHttpServletRequestWrapper requestWrapper;
@Before
public void setUp()
{
initMocks(this);
requestWrapper = new AdminConsoleHttpServletRequestWrapper(ADDITIONAL_HEADERS, request);
requestWrapper = new AdditionalHeadersHttpServletRequestWrapper(ADDITIONAL_HEADERS, request);
}
@Test(expected = AlfrescoRuntimeException.class)
public void wrapperShouldNotBeInstancedWithoutAdditionalHeaders()
{
new AdminConsoleHttpServletRequestWrapper(null, request);
new AdditionalHeadersHttpServletRequestWrapper(null, request);
}
@Test(expected = IllegalArgumentException.class)
public void wrapperShouldNotBeInstancedWithoutRequestsToWrap()
{
new AdminConsoleHttpServletRequestWrapper(new HashMap<>(), null);
new AdditionalHeadersHttpServletRequestWrapper(new HashMap<>(), null);
}
@Test
@@ -112,7 +111,7 @@ public class AdminConsoleHttpServletRequestWrapperUnitTest
{
when(request.getHeaderNames()).thenReturn(enumeration(DEFAULT_HEADERS.keySet()));
requestWrapper = new AdminConsoleHttpServletRequestWrapper(new HashMap<>(), request);
requestWrapper = new AdditionalHeadersHttpServletRequestWrapper(new HashMap<>(), request);
Enumeration<String> headerNames = requestWrapper.getHeaderNames();
assertNotNull("headerNames should not be null", headerNames);
assertTrue("headerNames should not be empty", headerNames.hasMoreElements());
@@ -164,7 +163,7 @@ public class AdminConsoleHttpServletRequestWrapperUnitTest
Map<String, String> overrideHeaders = new HashMap<>();
overrideHeaders.put(DEFAULT_HEADER, overrideHeaderValue);
requestWrapper = new AdminConsoleHttpServletRequestWrapper(overrideHeaders, request);
requestWrapper = new AdditionalHeadersHttpServletRequestWrapper(overrideHeaders, request);
String header = requestWrapper.getHeader(DEFAULT_HEADER);
assertEquals("The header should have the overridden value", overrideHeaderValue, header);
@@ -204,7 +203,7 @@ public class AdminConsoleHttpServletRequestWrapperUnitTest
Map<String, String> overrideHeaders = new HashMap<>();
overrideHeaders.put(DEFAULT_HEADER, overrideHeaderValue);
requestWrapper = new AdminConsoleHttpServletRequestWrapper(overrideHeaders, request);
requestWrapper = new AdditionalHeadersHttpServletRequestWrapper(overrideHeaders, request);
Enumeration<String> headers = requestWrapper.getHeaders(DEFAULT_HEADER);
assertNotNull("The headers enumeration should not be null", headers);
assertTrue("The headers enumeration should not be empty", headers.hasMoreElements());

View File

@@ -23,7 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.security.authentication.identityservice.admin;
package org.alfresco.repo.security.authentication.identityservice.authentication;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -46,7 +46,7 @@ import org.mockito.Mock;
import org.alfresco.repo.admin.SysAdminParams;
public class AdminConsoleAuthenticationCookiesServiceUnitTest
public class AdminAuthenticationCookiesServiceUnitTest
{
private static final int DEFAULT_COOKIE_LIFETIME = 86400;
private static final String COOKIE_NAME = "cookie";
@@ -59,13 +59,13 @@ public class AdminConsoleAuthenticationCookiesServiceUnitTest
private SysAdminParams sysAdminParams;
@Captor
private ArgumentCaptor<Cookie> cookieCaptor;
private AdminConsoleAuthenticationCookiesService cookiesService;
private AdminAuthenticationCookiesService cookiesService;
@Before
public void setUp()
{
initMocks(this);
cookiesService = new AdminConsoleAuthenticationCookiesService(sysAdminParams, DEFAULT_COOKIE_LIFETIME);
cookiesService = new AdminAuthenticationCookiesService(sysAdminParams, DEFAULT_COOKIE_LIFETIME);
}
@Test
@@ -138,7 +138,7 @@ public class AdminConsoleAuthenticationCookiesServiceUnitTest
public void cookieWithCustomMaxAgeShouldBeAddedToTheResponse()
{
int customMaxAge = 60;
cookiesService = new AdminConsoleAuthenticationCookiesService(sysAdminParams, customMaxAge);
cookiesService = new AdminAuthenticationCookiesService(sysAdminParams, customMaxAge);
when(sysAdminParams.getAlfrescoProtocol()).thenReturn("https");
cookiesService.addCookie(COOKIE_NAME, COOKIE_VALUE, response);

View File

@@ -23,7 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.security.authentication.identityservice.admin;
package org.alfresco.repo.security.authentication.identityservice.authentication.admin;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
@@ -58,11 +58,12 @@ import org.alfresco.repo.security.authentication.identityservice.IdentityService
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacade.AccessTokenAuthorization;
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacade.AuthorizationException;
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacade.AuthorizationGrant;
import org.alfresco.repo.security.authentication.identityservice.authentication.AdditionalHeadersHttpServletRequestWrapper;
import org.alfresco.repo.security.authentication.identityservice.authentication.AdminAuthenticationCookiesService;
@SuppressWarnings("PMD.AvoidStringBufferField")
public class IdentityServiceAdminConsoleAuthenticatorUnitTest
{
private static final String ALFRESCO_ACCESS_TOKEN = "ALFRESCO_ACCESS_TOKEN";
private static final String ALFRESCO_REFRESH_TOKEN = "ALFRESCO_REFRESH_TOKEN";
private static final String ALFRESCO_TOKEN_EXPIRATION = "ALFRESCO_TOKEN_EXPIRATION";
@@ -76,7 +77,7 @@ public class IdentityServiceAdminConsoleAuthenticatorUnitTest
@Mock
IdentityServiceConfig identityServiceConfig;
@Mock
AdminConsoleAuthenticationCookiesService cookiesService;
AdminAuthenticationCookiesService cookiesService;
@Mock
RemoteUserMapper remoteUserMapper;
@Mock
@@ -84,7 +85,7 @@ public class IdentityServiceAdminConsoleAuthenticatorUnitTest
@Mock
AccessToken accessToken;
@Captor
ArgumentCaptor<AdminConsoleHttpServletRequestWrapper> requestCaptor;
ArgumentCaptor<AdditionalHeadersHttpServletRequestWrapper> requestCaptor;
IdentityServiceAdminConsoleAuthenticator authenticator;
@@ -122,7 +123,7 @@ public class IdentityServiceAdminConsoleAuthenticatorUnitTest
String.valueOf(Instant.now().plusSeconds(60).toEpochMilli()));
when(remoteUserMapper.getRemoteUser(requestCaptor.capture())).thenReturn("admin");
String username = authenticator.getAdminConsoleUser(request, response);
String username = authenticator.getUserId(request, response);
assertEquals("Bearer JWT_TOKEN", requestCaptor.getValue().getHeader("Authorization"));
assertEquals("admin", username);
@@ -143,7 +144,7 @@ public class IdentityServiceAdminConsoleAuthenticatorUnitTest
when(identityServiceFacade.authorize(any(AuthorizationGrant.class))).thenReturn(accessTokenAuthorization);
when(remoteUserMapper.getRemoteUser(requestCaptor.capture())).thenReturn("admin");
String username = authenticator.getAdminConsoleUser(request, response);
String username = authenticator.getUserId(request, response);
verify(cookiesService).addCookie(ALFRESCO_ACCESS_TOKEN, "REFRESHED_JWT_TOKEN", response);
verify(cookiesService).addCookie(ALFRESCO_REFRESH_TOKEN, "REFRESH_TOKEN", response);
@@ -207,7 +208,7 @@ public class IdentityServiceAdminConsoleAuthenticatorUnitTest
when(identityServiceFacade.authorize(any(AuthorizationGrant.class))).thenThrow(AuthorizationException.class);
String username = authenticator.getAdminConsoleUser(request, response);
String username = authenticator.getUserId(request, response);
verify(cookiesService).resetCookie(ALFRESCO_ACCESS_TOKEN, response);
verify(cookiesService).resetCookie(ALFRESCO_REFRESH_TOKEN, response);
@@ -228,7 +229,7 @@ public class IdentityServiceAdminConsoleAuthenticatorUnitTest
.thenReturn(accessTokenAuthorization);
when(remoteUserMapper.getRemoteUser(requestCaptor.capture())).thenReturn("admin");
String username = authenticator.getAdminConsoleUser(request, response);
String username = authenticator.getUserId(request, response);
verify(cookiesService).addCookie(ALFRESCO_ACCESS_TOKEN, "JWT_TOKEN", response);
verify(cookiesService).addCookie(ALFRESCO_REFRESH_TOKEN, "REFRESH_TOKEN", response);
@@ -241,7 +242,7 @@ public class IdentityServiceAdminConsoleAuthenticatorUnitTest
{
when(remoteUserMapper.getRemoteUser(request)).thenReturn("admin");
String username = authenticator.getAdminConsoleUser(request, response);
String username = authenticator.getUserId(request, response);
assertEquals("admin", username);
}

View File

@@ -0,0 +1,253 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.security.authentication.identityservice.webscript;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import java.io.IOException;
import java.time.Instant;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import com.nimbusds.oauth2.sdk.Scope;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistration.ProviderDetails;
import org.alfresco.repo.security.authentication.external.RemoteUserMapper;
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceConfig;
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacade;
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacade.AccessToken;
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacade.AccessTokenAuthorization;
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacade.AuthorizationException;
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacade.AuthorizationGrant;
import org.alfresco.repo.security.authentication.identityservice.authentication.AdditionalHeadersHttpServletRequestWrapper;
import org.alfresco.repo.security.authentication.identityservice.authentication.AdminAuthenticationCookiesService;
import org.alfresco.repo.security.authentication.identityservice.authentication.webscripts.IdentityServiceWebScriptsHomeAuthenticator;
@SuppressWarnings("PMD.AvoidStringBufferField")
public class IdentityServiceWebScriptsHomeAuthenticatorUnitTest
{
private static final String ALFRESCO_ACCESS_TOKEN = "ALFRESCO_ACCESS_TOKEN";
private static final String ALFRESCO_REFRESH_TOKEN = "ALFRESCO_REFRESH_TOKEN";
private static final String ALFRESCO_TOKEN_EXPIRATION = "ALFRESCO_TOKEN_EXPIRATION";
@Mock
HttpServletRequest request;
@Mock
HttpServletResponse response;
@Mock
IdentityServiceFacade identityServiceFacade;
@Mock
IdentityServiceConfig identityServiceConfig;
@Mock
AdminAuthenticationCookiesService cookiesService;
@Mock
RemoteUserMapper remoteUserMapper;
@Mock
AccessTokenAuthorization accessTokenAuthorization;
@Mock
AccessToken accessToken;
@Captor
ArgumentCaptor<AdditionalHeadersHttpServletRequestWrapper> requestCaptor;
IdentityServiceWebScriptsHomeAuthenticator authenticator;
StringBuffer webScriptHomeURL = new StringBuffer("http://localhost:8080/alfresco/s/index");
@Before
public void setup()
{
initMocks(this);
ClientRegistration clientRegistration = mock(ClientRegistration.class);
ProviderDetails providerDetails = mock(ProviderDetails.class);
Scope scope = Scope.parse(Arrays.asList("openid", "profile", "email", "offline_access"));
when(clientRegistration.getProviderDetails()).thenReturn(providerDetails);
when(clientRegistration.getClientId()).thenReturn("alfresco");
when(providerDetails.getAuthorizationUri()).thenReturn("http://localhost:8999/auth");
when(providerDetails.getConfigurationMetadata()).thenReturn(Map.of("scopes_supported", scope));
when(identityServiceFacade.getClientRegistration()).thenReturn(clientRegistration);
when(request.getRequestURL()).thenReturn(webScriptHomeURL);
when(remoteUserMapper.getRemoteUser(request)).thenReturn(null);
authenticator = new IdentityServiceWebScriptsHomeAuthenticator();
authenticator.setActive(true);
authenticator.setIdentityServiceFacade(identityServiceFacade);
authenticator.setCookiesService(cookiesService);
authenticator.setRemoteUserMapper(remoteUserMapper);
authenticator.setIdentityServiceConfig(identityServiceConfig);
}
@Test
public void shouldCallRemoteMapperIfTokenIsInCookies()
{
when(cookiesService.getCookie(ALFRESCO_ACCESS_TOKEN, request)).thenReturn("JWT_TOKEN");
when(cookiesService.getCookie(ALFRESCO_TOKEN_EXPIRATION, request)).thenReturn(
String.valueOf(Instant.now().plusSeconds(60).toEpochMilli()));
when(remoteUserMapper.getRemoteUser(requestCaptor.capture())).thenReturn("admin");
String username = authenticator.getUserId(request, response);
assertEquals("Bearer JWT_TOKEN", requestCaptor.getValue().getHeader("Authorization"));
assertEquals("admin", username);
assertTrue(authenticator.isActive());
}
@Test
public void shouldRefreshExpiredTokenAndCallRemoteMapper()
{
when(cookiesService.getCookie(ALFRESCO_ACCESS_TOKEN, request)).thenReturn("EXPIRED_JWT_TOKEN");
when(cookiesService.getCookie(ALFRESCO_REFRESH_TOKEN, request)).thenReturn("REFRESH_TOKEN");
when(cookiesService.getCookie(ALFRESCO_TOKEN_EXPIRATION, request)).thenReturn(
String.valueOf(Instant.now().minusSeconds(60).toEpochMilli()));
when(accessToken.getTokenValue()).thenReturn("REFRESHED_JWT_TOKEN");
when(accessToken.getExpiresAt()).thenReturn(Instant.now().plusSeconds(60));
when(accessTokenAuthorization.getAccessToken()).thenReturn(accessToken);
when(accessTokenAuthorization.getRefreshTokenValue()).thenReturn("REFRESH_TOKEN");
when(identityServiceFacade.authorize(any(AuthorizationGrant.class))).thenReturn(accessTokenAuthorization);
when(remoteUserMapper.getRemoteUser(requestCaptor.capture())).thenReturn("admin");
String username = authenticator.getUserId(request, response);
verify(cookiesService).addCookie(ALFRESCO_ACCESS_TOKEN, "REFRESHED_JWT_TOKEN", response);
verify(cookiesService).addCookie(ALFRESCO_REFRESH_TOKEN, "REFRESH_TOKEN", response);
assertEquals("Bearer REFRESHED_JWT_TOKEN", requestCaptor.getValue().getHeader("Authorization"));
assertEquals("admin", username);
}
@Test
public void shouldCallAuthChallengeWebScriptHome() throws IOException
{
String redirectPath = "/alfresco/s/index";
when(request.getRequestURL()).thenReturn(webScriptHomeURL);
when(identityServiceConfig.getWebScriptsHomeScopes()).thenReturn(Set.of("openid", "email", "profile", "offline_access"));
when(identityServiceConfig.getWebScriptsHomeRedirectPath()).thenReturn(redirectPath);
ArgumentCaptor<String> authenticationRequest = ArgumentCaptor.forClass(String.class);
String expectedUri = "http://localhost:8999/auth?client_id=alfresco&redirect_uri=%s%s&response_type=code&scope="
.formatted("http://localhost:8080", redirectPath);
authenticator.requestAuthentication(request, response);
verify(response).sendRedirect(authenticationRequest.capture());
assertTrue(authenticationRequest.getValue().contains(expectedUri));
assertTrue(authenticationRequest.getValue().contains("openid"));
assertTrue(authenticationRequest.getValue().contains("profile"));
assertTrue(authenticationRequest.getValue().contains("email"));
assertTrue(authenticationRequest.getValue().contains("offline_access"));
assertTrue(authenticationRequest.getValue().contains("state"));
}
@Test
public void shouldCallAuthChallengeWebScriptHomeWithAudience() throws IOException
{
String audience = "http://localhost:8082";
String redirectPath = "/alfresco/s/index";
when(request.getRequestURL()).thenReturn(webScriptHomeURL);
when(identityServiceConfig.getAudience()).thenReturn(audience);
when(identityServiceConfig.getWebScriptsHomeRedirectPath()).thenReturn(redirectPath);
when(identityServiceConfig.getWebScriptsHomeScopes()).thenReturn(Set.of("openid", "email", "profile", "offline_access"));
ArgumentCaptor<String> authenticationRequest = ArgumentCaptor.forClass(String.class);
String expectedUri = "http://localhost:8999/auth?client_id=alfresco&redirect_uri=%s%s&response_type=code&scope="
.formatted("http://localhost:8080", redirectPath);
authenticator.requestAuthentication(request, response);
verify(response).sendRedirect(authenticationRequest.capture());
assertTrue(authenticationRequest.getValue().contains(expectedUri));
assertTrue(authenticationRequest.getValue().contains("openid"));
assertTrue(authenticationRequest.getValue().contains("profile"));
assertTrue(authenticationRequest.getValue().contains("email"));
assertTrue(authenticationRequest.getValue().contains("offline_access"));
assertTrue(authenticationRequest.getValue().contains("audience=%s".formatted(audience)));
assertTrue(authenticationRequest.getValue().contains("state"));
}
@Test
public void shouldResetCookiesAndCallAuthChallenge() throws IOException
{
when(cookiesService.getCookie(ALFRESCO_ACCESS_TOKEN, request)).thenReturn("EXPIRED_JWT_TOKEN");
when(cookiesService.getCookie(ALFRESCO_REFRESH_TOKEN, request)).thenReturn("REFRESH_TOKEN");
when(cookiesService.getCookie(ALFRESCO_TOKEN_EXPIRATION, request)).thenReturn(
String.valueOf(Instant.now().minusSeconds(60).toEpochMilli()));
when(identityServiceFacade.authorize(any(AuthorizationGrant.class))).thenThrow(AuthorizationException.class);
String username = authenticator.getUserId(request, response);
verify(cookiesService).resetCookie(ALFRESCO_ACCESS_TOKEN, response);
verify(cookiesService).resetCookie(ALFRESCO_REFRESH_TOKEN, response);
verify(cookiesService).resetCookie(ALFRESCO_TOKEN_EXPIRATION, response);
assertNull(username);
}
@Test
public void shouldAuthorizeCodeAndSetCookies()
{
when(request.getParameter("code")).thenReturn("auth_code");
when(accessToken.getTokenValue()).thenReturn("JWT_TOKEN");
when(accessToken.getExpiresAt()).thenReturn(Instant.now().plusSeconds(60));
when(accessTokenAuthorization.getAccessToken()).thenReturn(accessToken);
when(accessTokenAuthorization.getRefreshTokenValue()).thenReturn("REFRESH_TOKEN");
when(identityServiceFacade.authorize(
AuthorizationGrant.authorizationCode("auth_code", webScriptHomeURL.toString())))
.thenReturn(accessTokenAuthorization);
when(remoteUserMapper.getRemoteUser(requestCaptor.capture())).thenReturn("admin");
String username = authenticator.getUserId(request, response);
verify(cookiesService).addCookie(ALFRESCO_ACCESS_TOKEN, "JWT_TOKEN", response);
verify(cookiesService).addCookie(ALFRESCO_REFRESH_TOKEN, "REFRESH_TOKEN", response);
assertEquals("Bearer JWT_TOKEN", requestCaptor.getValue().getHeader("Authorization"));
assertEquals("admin", username);
}
@Test
public void shouldExtractUsernameFromAuthorizationHeader()
{
when(remoteUserMapper.getRemoteUser(request)).thenReturn("admin");
String username = authenticator.getUserId(request, response);
assertEquals("admin", username);
}
}

View File

@@ -25,26 +25,19 @@
*/
package org.alfresco.repo.site;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import org.springframework.extensions.surf.util.I18NUtil;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.transaction.annotation.Transactional;
@@ -56,6 +49,8 @@ import org.alfresco.query.PagingRequest;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.admin.SysAdminParams;
import org.alfresco.repo.admin.SysAdminParamsImpl;
import org.alfresco.repo.cache.MemoryCache;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.dictionary.DictionaryDAO;
import org.alfresco.repo.dictionary.M2Model;
import org.alfresco.repo.dictionary.M2Property;
@@ -65,6 +60,7 @@ import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
import org.alfresco.repo.node.archive.NodeArchiveService;
import org.alfresco.repo.node.getchildren.FilterProp;
import org.alfresco.repo.node.getchildren.FilterPropString;
import org.alfresco.repo.search.EmptyResultSet;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
@@ -78,21 +74,10 @@ import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.CopyService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.ScriptLocation;
import org.alfresco.service.cmr.repository.ScriptService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.repository.*;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.*;
import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteMemberInfo;
import org.alfresco.service.cmr.site.SiteService;
@@ -3129,4 +3114,34 @@ public class SiteServiceImplTest extends BaseAlfrescoSpringTest
siteService.deleteSite(shortName);
}
@Test
public void testFindSitesQueryWithReservedCharacter()
{
// given
SiteServiceImpl cut = new SiteServiceImpl();
ArgumentCaptor<SearchParameters> searchParametersCaptor = ArgumentCaptor.forClass(SearchParameters.class);
SimpleCache<String, Object> cache = new MemoryCache<>();
cache.put("key.sitehome.noderef", new NodeRef("mock", "mock", "mock"));
cut.setSingletonCache(cache);
SearchService searchService = Mockito.mock(SearchService.class);
cut.setSearchService(searchService);
when(searchService.query(any(SearchParameters.class))).thenReturn(new EmptyResultSet());
// when
cut.findSites("-chu", 5);
// then
verify(searchService).query(searchParametersCaptor.capture());
SearchParameters actualSearchParameters = searchParametersCaptor.getValue();
assertThat(actualSearchParameters.getQuery())
.isEqualTo("+TYPE:\"{http://www.alfresco.org/model/site/1.0}site\""
+ " AND ( cm:name:\"\\-chu*\""
+ " OR cm:title: (\"\\-chu*\" )"
+ " OR cm:description:\"\\-chu\")");
}
}

View File

@@ -1 +0,0 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -1,17 +0,0 @@
#!/usr/bin/env bash
echo "=========================== Starting Add Step Summary Script ==========================="
PS4="\[\e[35m\]+ \[\e[m\]"
set -vex
echo "#### ⏱ Before Tests: $(date -u +'%Y-%m-%d %H:%M:%S%:z')" >> $GITHUB_STEP_SUMMARY
echo "#### ⚙ Configuration" >> $GITHUB_STEP_SUMMARY
if [[ "$RP_ENABLED" == 'true' ]]; then
echo "- [Report Portal]($RP_URL) configured with key "'`'$RP_KEY'`' >> $GITHUB_STEP_SUMMARY
else
echo "- Report Portal not enabled" >> $GITHUB_STEP_SUMMARY
fi
set +vex
echo "=========================== Finishing Add Step Summary Script =========================="