Compare commits

...

6 Commits

Author SHA1 Message Date
Travis CI User
8524ca9d67 [maven-release-plugin][skip ci] prepare for next development iteration 2021-04-27 16:26:07 +00:00
Travis CI User
acfc2385a5 [maven-release-plugin][skip ci] prepare release 8.300.2 2021-04-27 16:26:01 +00:00
Angel Borroy
174389523d SEARCH-2802: HttpClientFactory (for Repository and Search Services clients) support for Shared Secret communication.
Cherry picked from fef8cc9 and 20dd0ef
2021-04-27 18:21:02 +02:00
Travis CI User
f4593e1a21 [maven-release-plugin][skip ci] prepare for next development iteration 2021-04-27 15:48:13 +00:00
Travis CI User
1a4cf7c7b3 [maven-release-plugin][skip ci] prepare release 8.300.1 2021-04-27 15:48:07 +00:00
alandavis
54ad5e403c SEARCH-2802 Create special branch to support Search Services 1.4 going forwards
Only need core and data-model
2021-04-27 16:33:31 +01:00
28 changed files with 712 additions and 651 deletions

View File

@@ -32,25 +32,25 @@ stages:
if: commit_message !~ /\[skip tests\]/
- name: release
if: fork = false AND (branch = master OR branch =~ /release\/.*/) AND type != pull_request AND commit_message !~ /\[no release\]/
- name: update_downstream
if: fork = false AND (branch = master OR branch =~ /release\/.*/) AND type != pull_request AND commit_message !~ /\[no downstream\]/
- name: trigger_downstream
if: fork = false AND (branch != master AND branch !~ /release\/.*/) AND type != pull_request AND commit_message !~ /\[no downstream\]/
# - name: update_downstream
# if: fork = false AND (branch = master OR branch =~ /release\/.*/) AND type != pull_request AND commit_message !~ /\[no downstream\]/
# - name: trigger_downstream
# if: fork = false AND (branch != master AND branch !~ /release\/.*/) AND type != pull_request AND commit_message !~ /\[no downstream\]/
before_install: travis_retry bash scripts/travis/init.sh
install: travis_retry travis_wait 40 bash scripts/travis/build.sh
jobs:
include:
- name: "WhiteSource scan"
stage: test
# only on release branches or master and if it is not a PR
if: fork = false AND (branch = master OR branch =~ /release\/.*/) AND type != pull_request
script:
# Download the latest version of WhiteSource Unified Agent
- curl -LJO https://github.com/whitesource/unified-agent-distribution/releases/latest/download/wss-unified-agent.jar
# Run WhiteSource Unified Agent
- java -jar wss-unified-agent.jar -apiKey ${WHITESOURCE_API_KEY} -c .wss-unified-agent.config -d ./packaging/war
# - name: "WhiteSource scan"
# stage: test
# # only on release branches or master and if it is not a PR
# if: fork = false AND (branch = master OR branch =~ /release\/.*/) AND type != pull_request
# script:
# # Download the latest version of WhiteSource Unified Agent
# - curl -LJO https://github.com/whitesource/unified-agent-distribution/releases/latest/download/wss-unified-agent.jar
# # Run WhiteSource Unified Agent
# - java -jar wss-unified-agent.jar -apiKey ${WHITESOURCE_API_KEY} -c .wss-unified-agent.config -d ./packaging/war
# - name: "Source Clear Scan"
# # only on release branches or master and if it is not a PR
@@ -59,194 +59,194 @@ jobs:
# addons:
# srcclr: true
- name: "Core, Data-Model, Repository - AllUnitTestsSuite - Build and test"
- name: "Core, Data-Model - AllUnitTestsSuite - Build and test"
script:
- travis_retry mvn -B test -pl core,data-model
- travis_retry mvn -B test -pl repository -Dtest=AllUnitTestsSuite
# - travis_retry mvn -B test -pl repository -Dtest=AllUnitTestsSuite
- name: "Repository - AppContext01TestSuite"
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContext01TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - AppContext02TestSuite"
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContext02TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - AppContext03TestSuite"
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.3.5
script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContext03TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco -Dalfresco-pdf-renderer.url=http://localhost:8090/ -Djodconverter.url=http://localhost:8090/ -Dimg.url=http://localhost:8090/ -Dtika.url=http://localhost:8090/ -Dtransform.misc.url=http://localhost:8090/
- name: "Repository - AppContext04TestSuite"
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.3.5
script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContext04TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - AppContext05TestSuite"
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
- mkdir -p "${HOME}/tmp"
- cp repository/src/test/resources/realms/alfresco-realm.json "${HOME}/tmp"
- export HOST_IP=$(hostname -I | cut -f1 -d' ')
- docker run -d -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin -e DB_VENDOR=h2 -p 8999:8080 -e KEYCLOAK_IMPORT=/tmp/alfresco-realm.json -v $HOME/tmp/alfresco-realm.json:/tmp/alfresco-realm.json quay.io/alfresco/alfresco-identity-service:1.2
script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContext05TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco "-Didentity-service.auth-server-url=http://${HOST_IP}:8999/auth"
- name: "Repository - AppContext06TestSuite"
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.3.5
script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContext06TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco -Dalfresco-pdf-renderer.url=http://localhost:8090/ -Djodconverter.url=http://localhost:8090/ -Dimg.url=http://localhost:8090/ -Dtika.url=http://localhost:8090/ -Dtransform.misc.url=http://localhost:8090/
- name: "Repository - AppContextExtraTestSuite"
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContextExtraTestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - MiscContextTestSuite"
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.3.5
script: travis_wait 20 mvn -B test -pl repository -Dtest=MiscContextTestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco -Dalfresco-pdf-renderer.url=http://localhost:8090/ -Djodconverter.url=http://localhost:8090/ -Dimg.url=http://localhost:8090/ -Dtika.url=http://localhost:8090/ -Dtransform.misc.url=http://localhost:8090/
- name: "Repository - MySQL tests"
if: commit_message !~ /\[skip db\]/
before_script:
- docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=alfresco -e MYSQL_USER=alfresco -e MYSQL_DATABASE=alfresco -e MYSQL_PASSWORD=alfresco mysql:5.7.23 --transaction-isolation='READ-COMMITTED'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
script: travis_wait 20 mvn -B test -pl repository -Dtest=AllDBTestsTestSuite -Ddb.driver=com.mysql.jdbc.Driver -Ddb.name=alfresco -Ddb.url=jdbc:mysql://localhost:3307/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - PostgreSQL 10 tests"
if: commit_message !~ /\[skip db\]/
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:10.9 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
script: travis_wait 20 mvn -B test -pl repository -Dtest=AllDBTestsTestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - PostgreSQL 11 tests"
if: commit_message !~ /\[skip db\]/
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
script: travis_wait 20 mvn -B test -pl repository -Dtest=AllDBTestsTestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Repository - MariaDB tests"
if: commit_message !~ /\[skip db\]/
before_script:
- docker run -d -p 3307:3306 --name mariadb -e MYSQL_ROOT_PASSWORD=alfresco -e MYSQL_USER=alfresco -e MYSQL_DATABASE=alfresco -e MYSQL_PASSWORD=alfresco mariadb:10.2.18 --transaction-isolation=READ-COMMITTED --max-connections=300 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
script: travis_wait 20 mvn -B test -pl repository -Dtest=AllDBTestsTestSuite -Ddb.name=alfresco -Ddb.url=jdbc:mariadb://localhost:3307/alfresco?useUnicode=yes\&characterEncoding=UTF-8 -Ddb.username=alfresco -Ddb.password=alfresco -Ddb.driver=org.mariadb.jdbc.Driver
- name: "Remote-api - AppContext01TestSuite"
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContext01TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Remote-api - AppContext02TestSuite"
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContext02TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Remote-api - AppContext03TestSuite"
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContext03TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Remote-api - AppContext04TestSuite"
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContext04TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "Remote-api - AppContextExtraTestSuite"
before_script:
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContextExtraTestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
- name: "REST API TAS tests part1"
if: commit_message =~ /\[tas\]/
before_script:
- ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal+transforms.yml
- ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
script:
- travis_wait 60 mvn -B install -f packaging/tests/tas-restapi/pom.xml -Pall-tas-tests,run-restapi-part1 -Denvironment=default -DrunBugs=false
- name: "REST API TAS tests part2"
if: commit_message =~ /\[tas\]/
before_script:
- ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal+transforms.yml
- ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
script:
- travis_wait 60 mvn -B install -f packaging/tests/tas-restapi/pom.xml -Pall-tas-tests,run-restapi-part2 -Denvironment=default -DrunBugs=false
- name: "REST API TAS tests part3"
if: commit_message =~ /\[tas\]/
before_script:
- ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal+transforms.yml
- ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
script:
- travis_wait 60 mvn -B install -f packaging/tests/tas-restapi/pom.xml -Pall-tas-tests,run-restapi-part3 -Denvironment=default -DrunBugs=false
- name: "CMIS TAS tests"
if: commit_message =~ /\[tas\]/
before_script:
- ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal+transforms.yml
- ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
script:
- travis_wait 40 mvn -B install -f packaging/tests/tas-cmis/pom.xml -Pall-tas-tests -Denvironment=default -DrunBugs=false
- name: "Email TAS tests"
if: commit_message =~ /\[tas\]/
before_script:
- ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal.yml
- ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
script:
- travis_wait 30 mvn -B install -f packaging/tests/tas-email/pom.xml -Pall-tas-tests -Denvironment=default -DrunBugs=false
- name: "WebDAV TAS tests"
if: commit_message =~ /\[tas\]/
before_script:
- ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal.yml
- ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
script:
- travis_wait 30 mvn -B install -f packaging/tests/tas-webdav/pom.xml -Pall-tas-tests -Denvironment=default -DrunBugs=false
- name: "Integration TAS tests"
if: commit_message =~ /\[tas\]/
before_script:
- ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal.yml
- ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
script:
- travis_wait 30 mvn -B install -f packaging/tests/tas-integration/pom.xml -Pall-tas-tests -Denvironment=default -DrunBugs=false
# - name: "Repository - AppContext01TestSuite"
# before_script:
# - docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
# - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
# script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContext01TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
#
# - name: "Repository - AppContext02TestSuite"
# before_script:
# - docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
# - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
# script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContext02TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
#
# - name: "Repository - AppContext03TestSuite"
# before_script:
# - docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
# - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
# - docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.3.5
# script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContext03TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco -Dalfresco-pdf-renderer.url=http://localhost:8090/ -Djodconverter.url=http://localhost:8090/ -Dimg.url=http://localhost:8090/ -Dtika.url=http://localhost:8090/ -Dtransform.misc.url=http://localhost:8090/
#
# - name: "Repository - AppContext04TestSuite"
# before_script:
# - docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
# - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
# - docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.3.5
# script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContext04TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
#
# - name: "Repository - AppContext05TestSuite"
# before_script:
# - docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
# - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
# - mkdir -p "${HOME}/tmp"
# - cp repository/src/test/resources/realms/alfresco-realm.json "${HOME}/tmp"
# - export HOST_IP=$(hostname -I | cut -f1 -d' ')
# - docker run -d -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin -e DB_VENDOR=h2 -p 8999:8080 -e KEYCLOAK_IMPORT=/tmp/alfresco-realm.json -v $HOME/tmp/alfresco-realm.json:/tmp/alfresco-realm.json quay.io/alfresco/alfresco-identity-service:1.2
# script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContext05TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco "-Didentity-service.auth-server-url=http://${HOST_IP}:8999/auth"
#
# - name: "Repository - AppContext06TestSuite"
# before_script:
# - docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
# - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
# - docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.3.5
# script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContext06TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco -Dalfresco-pdf-renderer.url=http://localhost:8090/ -Djodconverter.url=http://localhost:8090/ -Dimg.url=http://localhost:8090/ -Dtika.url=http://localhost:8090/ -Dtransform.misc.url=http://localhost:8090/
#
# - name: "Repository - AppContextExtraTestSuite"
# before_script:
# - docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
# - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
# script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContextExtraTestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
#
# - name: "Repository - MiscContextTestSuite"
# before_script:
# - docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
# - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
# - docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.3.5
# script: travis_wait 20 mvn -B test -pl repository -Dtest=MiscContextTestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco -Dalfresco-pdf-renderer.url=http://localhost:8090/ -Djodconverter.url=http://localhost:8090/ -Dimg.url=http://localhost:8090/ -Dtika.url=http://localhost:8090/ -Dtransform.misc.url=http://localhost:8090/
#
# - name: "Repository - MySQL tests"
# if: commit_message !~ /\[skip db\]/
# before_script:
# - docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=alfresco -e MYSQL_USER=alfresco -e MYSQL_DATABASE=alfresco -e MYSQL_PASSWORD=alfresco mysql:5.7.23 --transaction-isolation='READ-COMMITTED'
# - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
# script: travis_wait 20 mvn -B test -pl repository -Dtest=AllDBTestsTestSuite -Ddb.driver=com.mysql.jdbc.Driver -Ddb.name=alfresco -Ddb.url=jdbc:mysql://localhost:3307/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
#
# - name: "Repository - PostgreSQL 10 tests"
# if: commit_message !~ /\[skip db\]/
# before_script:
# - docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:10.9 postgres -c 'max_connections=300'
# - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
# script: travis_wait 20 mvn -B test -pl repository -Dtest=AllDBTestsTestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
#
# - name: "Repository - PostgreSQL 11 tests"
# if: commit_message !~ /\[skip db\]/
# before_script:
# - docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
# - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
# script: travis_wait 20 mvn -B test -pl repository -Dtest=AllDBTestsTestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
#
# - name: "Repository - MariaDB tests"
# if: commit_message !~ /\[skip db\]/
# before_script:
# - docker run -d -p 3307:3306 --name mariadb -e MYSQL_ROOT_PASSWORD=alfresco -e MYSQL_USER=alfresco -e MYSQL_DATABASE=alfresco -e MYSQL_PASSWORD=alfresco mariadb:10.2.18 --transaction-isolation=READ-COMMITTED --max-connections=300 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
# - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
# script: travis_wait 20 mvn -B test -pl repository -Dtest=AllDBTestsTestSuite -Ddb.name=alfresco -Ddb.url=jdbc:mariadb://localhost:3307/alfresco?useUnicode=yes\&characterEncoding=UTF-8 -Ddb.username=alfresco -Ddb.password=alfresco -Ddb.driver=org.mariadb.jdbc.Driver
#
# - name: "Remote-api - AppContext01TestSuite"
# before_script:
# - docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
# - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
# script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContext01TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
#
# - name: "Remote-api - AppContext02TestSuite"
# before_script:
# - docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
# - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
# script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContext02TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
#
# - name: "Remote-api - AppContext03TestSuite"
# before_script:
# - docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
# - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
# script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContext03TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
#
# - name: "Remote-api - AppContext04TestSuite"
# before_script:
# - docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
# - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
# script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContext04TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
#
# - name: "Remote-api - AppContextExtraTestSuite"
# before_script:
# - docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.7 postgres -c 'max_connections=300'
# - docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
# script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContextExtraTestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
#
# - name: "REST API TAS tests part1"
# if: commit_message =~ /\[tas\]/
# before_script:
# - ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal+transforms.yml
# - ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
# script:
# - travis_wait 60 mvn -B install -f packaging/tests/tas-restapi/pom.xml -Pall-tas-tests,run-restapi-part1 -Denvironment=default -DrunBugs=false
#
# - name: "REST API TAS tests part2"
# if: commit_message =~ /\[tas\]/
# before_script:
# - ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal+transforms.yml
# - ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
# script:
# - travis_wait 60 mvn -B install -f packaging/tests/tas-restapi/pom.xml -Pall-tas-tests,run-restapi-part2 -Denvironment=default -DrunBugs=false
#
# - name: "REST API TAS tests part3"
# if: commit_message =~ /\[tas\]/
# before_script:
# - ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal+transforms.yml
# - ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
# script:
# - travis_wait 60 mvn -B install -f packaging/tests/tas-restapi/pom.xml -Pall-tas-tests,run-restapi-part3 -Denvironment=default -DrunBugs=false
#
# - name: "CMIS TAS tests"
# if: commit_message =~ /\[tas\]/
# before_script:
# - ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal+transforms.yml
# - ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
# script:
# - travis_wait 40 mvn -B install -f packaging/tests/tas-cmis/pom.xml -Pall-tas-tests -Denvironment=default -DrunBugs=false
#
# - name: "Email TAS tests"
# if: commit_message =~ /\[tas\]/
# before_script:
# - ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal.yml
# - ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
# script:
# - travis_wait 30 mvn -B install -f packaging/tests/tas-email/pom.xml -Pall-tas-tests -Denvironment=default -DrunBugs=false
#
# - name: "WebDAV TAS tests"
# if: commit_message =~ /\[tas\]/
# before_script:
# - ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal.yml
# - ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
# script:
# - travis_wait 30 mvn -B install -f packaging/tests/tas-webdav/pom.xml -Pall-tas-tests -Denvironment=default -DrunBugs=false
#
# - name: "Integration TAS tests"
# if: commit_message =~ /\[tas\]/
# before_script:
# - ${TAS_SCRIPTS}/start-compose.sh ${TAS_ENVIRONMENT}/docker-compose-minimal.yml
# - ${TAS_SCRIPTS}/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
# script:
# - travis_wait 30 mvn -B install -f packaging/tests/tas-integration/pom.xml -Pall-tas-tests -Denvironment=default -DrunBugs=false
- name: "Push to Nexus"
stage: release
before_script: bash scripts/travis/verify_release_tag.sh
script: travis_wait 40 bash scripts/travis/maven_release.sh
- name: "Update alfresco-enterprise-repo"
stage: update_downstream
install: skip
script: bash scripts/travis/update_downstream.sh
- name: "Trigger alfresco-enterprise-repo build"
stage: trigger_downstream
before_install: skip
install: skip
script: bash scripts/travis/trigger_travis.sh "Alfresco" "alfresco-enterprise-repo" "${TRAVIS_BRANCH}"
# - name: "Update alfresco-enterprise-repo"
# stage: update_downstream
# install: skip
# script: bash scripts/travis/update_downstream.sh
#
# - name: "Trigger alfresco-enterprise-repo build"
# stage: trigger_downstream
# before_install: skip
# install: skip
# script: bash scripts/travis/trigger_travis.sh "Alfresco" "alfresco-enterprise-repo" "${TRAVIS_BRANCH}"

148
README.md
View File

@@ -2,150 +2,4 @@
[![Build Status](https://travis-ci.com/Alfresco/alfresco-community-repo.svg?branch=master)](https://travis-ci.com/Alfresco/alfresco-community-repo)
This project contains the bulk of the [Alfresco Content Services Repository](https://community.alfresco.com/docs/DOC-6385-project-overview-repository) code.
To make the development process simpler, it brings together code historically in `alfresco-core`,
`alfresco-data-madel`, `alfresco-repository`, `alfresco-remote-api` and repository specific
tests and war file creation from `acs-community-packaging`. They exist as sub projects within the Maven Reactor and still
create the same artifacts.
#### Alfresco Core
Alfresco Core is a library packaged as a jar file which contains the following:
* Various helpers and utils
* Canned queries interface and supporting classes
* Generic encryption supporting classes
Version 7 of the library uses Spring 5, Quartz 2.3 and does not have Hibernate dependency.
#### Alfresco Data Model
Data model is a library packaged as a jar file which contains the following:
* Dictionary, Repository and Search Services interfaces
* Models for data types and Dictionary implementation
* Parsers
#### Alfresco Repository
Repository is a library packaged as a jar file which contains the following:
* DAOs and SQL scripts
* Various Service implementations
* Utility classes
Tests are combined into test classes split by test type or Spring application context used in the test, see classes
in _src/test/java/org/alfresco_. All of these classes as well as individual tests can be run by specifying the test
class name and a set of DB connection properties. Check the travis.yml file for docker images that should be started
to provide a sutable test environment. For example:
~~~
mvn clean test -Dtest=SomeRepoTest -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql:alfresco -Ddb.username=alfresco -Ddb.password=alfresco
~~~
#### Alfresco Remote API
Remote API is a library packaged as a jar file which contains the following:
* REST API framework
* WebScript implementations including [V1 REST APIs](https://community.alfresco.com/community/ecm/blog/2017/05/02/v1-rest-api-10-things-you-should-know)
* [OpenCMIS](https://chemistry.apache.org/java/opencmis.html) implementations
Like the `alfresco-repository` tests are combined in test classes split by test type or Spring application context used
in the test.
#### Artifacts
The artifacts can be obtained by:
* downloading from [Alfresco maven repository](https://artifacts.alfresco.com/nexus/content/groups/public)
* getting as Maven dependency by adding the dependency to your pom file:
~~~
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-core</artifactId>
<version>version</version>
</dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-data-model</artifactId>
<version>version</version>
</dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-repository</artifactId>
<version>version</version>
</dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-remote-api</artifactId>
<version>version</version>
</dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>content-services-community</artifactId>
<version>version</version>
<type>war</type>
</dependency>
~~~
and Alfresco maven repository:
~~~
<repository>
<id>alfresco-maven-repo</id>
<url>https://artifacts.alfresco.com/nexus/content/groups/public</url>
</repository>
~~~
The SNAPSHOT versions of the artifact are not published.
All current source versions are held in github. Historic versions can be found in [Alfresco SVN](https://svn.alfresco.com/repos/alfresco-open-mirror/services/alfresco-core/)
### Contributing guide
Please use [this guide](CONTRIBUTING.md) to make a contribution to the project.
## Setting up your development environment
Although it is possible to work on individual github projects, we recommend working on
the `alfresco-community-repo`, `alfresco-enterprise-repo`, `acs-packaging` and `acs-community-packaging`
in a single Intellij IDEA project. They depend on each other and typically you
will want to make changes to all of them if you are changing the repository code.
In the case of older branches, there is generally no need for the `acs-community-packaging` as you will
not be creating a community release.
Although it is possible to work on individual github projects, we recommend working on the `alfresco-community-repo`
and `acs-community-packaging` in a single Intellij IDEA project. They depend on each other and typically you will
want to make changes to both of them if you are changing the repository code.
~~~
$ mkdir work
$ cd work
$ git clone git@github.com:Alfresco/alfresco-community-repo.git
$ git clone git@github.com:Alfresco/acs-community-packaging.git
~~~
If you wish to build these projects from the command line, use the following commands.
~~~
$ cd alfresco-community-repo
$ mvn clean install -PcommunityDocker -DskipTests=true -Dversion.edition=Community
$ cd ..
$ cd acs-community-packaging
$ mvn clean install -PcommunityDocker -Dmaven.javadoc.skip=true
$ cd ..
~~~
In Itellij IDEA, create a new project using the `work` directory as the source.
* File > New Project from Existing Sources > .../work > Maven
## Docker
We generally use Docker for testing. In order to reduce the size of images we also supply a squash option that collapses
the layers in the image. This is a long-standing experimental feature that we have fould useful. However you will need
to enable experimental features in your Docker Engine.
~~~
{
"experimental": true,
"debug": true
}
~~~
## Branches
As multiple projects have been combined, branch names use the ACS version they are targeting.
For example the code used to create the repository in ACS 6.2.1 in a branch called `releases/6.2.1`.
The actual version number of the **repository artifacts** created by `alfresco-community-repo` are however different.
For example `release/6.2.1` artifacts are `7.183.x`. This adds some complexity, but ensures that
version numbers do not go backwards in existing releases. It also provides some level of
independence between the repository and other ACS components.
This is a special branch to support ongoing changes to Search Services 1.4.N

View File

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

View File

@@ -21,7 +21,6 @@ package org.alfresco.httpclient;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.AlgorithmParameters;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -32,14 +31,11 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.alfresco.encryption.AlfrescoKeyStore;
import org.alfresco.encryption.AlfrescoKeyStoreImpl;
import org.alfresco.encryption.EncryptionUtils;
import org.alfresco.encryption.Encryptor;
import org.alfresco.encryption.KeyProvider;
import org.alfresco.encryption.KeyResourceLoader;
import org.alfresco.encryption.KeyStoreParameters;
import org.alfresco.encryption.ssl.AuthSSLProtocolSocketFactory;
import org.alfresco.encryption.ssl.SSLEncryptionParameters;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.util.Pair;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
@@ -53,8 +49,6 @@ import org.apache.commons.httpclient.SimpleHttpConnectionManager;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.DefaultHttpParams;
import org.apache.commons.httpclient.params.DefaultHttpParamsFactory;
import org.apache.commons.httpclient.params.HttpClientParams;
@@ -75,23 +69,25 @@ import org.apache.commons.logging.LogFactory;
*/
public class HttpClientFactory
{
/**
* Communication type for HttpClient:
* - NONE is plain http
* - SECRET is plain http with a shared secret via request header
* - HTTPS is mTLS with client authentication (certificates are required)
*/
public static enum SecureCommsType
{
HTTPS, NONE;
HTTPS, NONE, SECRET;
public static SecureCommsType getType(String type)
{
if(type.equalsIgnoreCase("https"))
switch (type.toLowerCase())
{
return HTTPS;
}
else if(type.equalsIgnoreCase("none"))
{
return NONE;
}
else
{
throw new IllegalArgumentException("Invalid communications type");
case "https": return HTTPS;
case "none": return NONE;
case "secret": return SECRET;
default: throw new IllegalArgumentException("Invalid communications type");
}
}
};
@@ -122,14 +118,24 @@ public class HttpClientFactory
private int connectionTimeout = 0;
// Shared secret parameters
private String sharedSecret;
private String sharedSecretHeader = DEFAULT_SHAREDSECRET_HEADER;
// Default name for HTTP Request Header when using shared secret communication
public static final String DEFAULT_SHAREDSECRET_HEADER = "X-Alfresco-Search-Secret";
public HttpClientFactory()
{
}
/**
* Default constructor for legacy subsystems.
*/
public HttpClientFactory(SecureCommsType secureCommsType, SSLEncryptionParameters sslEncryptionParameters,
KeyResourceLoader keyResourceLoader, KeyStoreParameters keyStoreParameters,
MD5EncryptionParameters encryptionParameters, String host, int port, int sslPort, int maxTotalConnections,
int maxHostConnections, int socketTimeout)
KeyResourceLoader keyResourceLoader, KeyStoreParameters keyStoreParameters,
MD5EncryptionParameters encryptionParameters, String host, int port, int sslPort,
int maxTotalConnections, int maxHostConnections, int socketTimeout)
{
this.secureCommsType = secureCommsType;
this.sslEncryptionParameters = sslEncryptionParameters;
@@ -145,6 +151,21 @@ public class HttpClientFactory
init();
}
/**
* Recommended constructor for subsystems supporting Shared Secret communication.
* This constructor supports Shared Secret ("secret") communication method additionally to the legacy ones: "none" and "https".
*/
public HttpClientFactory(SecureCommsType secureCommsType, SSLEncryptionParameters sslEncryptionParameters,
KeyResourceLoader keyResourceLoader, KeyStoreParameters keyStoreParameters,
MD5EncryptionParameters encryptionParameters, String sharedSecret, String sharedSecretHeader,
String host, int port, int sslPort, int maxTotalConnections, int maxHostConnections, int socketTimeout)
{
this(secureCommsType, sslEncryptionParameters, keyResourceLoader, keyStoreParameters, encryptionParameters,
host, port, sslPort, maxTotalConnections, maxHostConnections, socketTimeout);
this.sharedSecret = sharedSecret;
this.sharedSecretHeader = sharedSecretHeader;
}
public void init()
{
this.sslKeyStore = new AlfrescoKeyStoreImpl(sslEncryptionParameters.getKeyStoreParameters(), keyResourceLoader);
@@ -272,10 +293,44 @@ public class HttpClientFactory
this.connectionTimeout = connectionTimeout;
}
protected HttpClient constructHttpClient()
/**
* Shared secret used for SECRET communication
* @param secret shared secret word
*/
public void setSharedSecret(String sharedSecret)
{
this.sharedSecret = sharedSecret;
}
/**
* @return Shared secret used for SECRET communication
*/
public String getSharedSecret()
{
return sharedSecret;
}
/**
* HTTP Request header used for SECRET communication
* @param sharedSecretHeader HTTP Request header
*/
public void setSharedSecretHeader(String sharedSecretHeader)
{
this.sharedSecretHeader = sharedSecretHeader;
}
/**
* @return HTTP Request header used for SECRET communication
*/
public String getSharedSecretHeader()
{
return sharedSecretHeader;
}
protected RequestHeadersHttpClient constructHttpClient()
{
MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
HttpClient httpClient = new HttpClient(connectionManager);
RequestHeadersHttpClient httpClient = new RequestHeadersHttpClient(connectionManager);
HttpClientParams params = httpClient.getParams();
params.setBooleanParameter(HttpConnectionParams.TCP_NODELAY, true);
params.setBooleanParameter(HttpConnectionParams.STALE_CONNECTION_CHECK, true);
@@ -291,15 +346,15 @@ public class HttpClientFactory
return httpClient;
}
protected HttpClient getHttpsClient()
protected RequestHeadersHttpClient getHttpsClient()
{
return getHttpsClient(host, sslPort);
}
protected HttpClient getHttpsClient(String httpsHost, int httpsPort)
protected RequestHeadersHttpClient getHttpsClient(String httpsHost, int httpsPort)
{
// Configure a custom SSL socket factory that will enforce mutual authentication
HttpClient httpClient = constructHttpClient();
RequestHeadersHttpClient httpClient = constructHttpClient();
// Default port is 443 for the HostFactory, when including customised port (like 8983) the port name is skipped from "getHostURL" string
HttpHostFactory hostFactory = new HttpHostFactory(new Protocol("https", sslSocketFactory, HttpsURL.DEFAULT_PORT));
httpClient.setHostConfiguration(new HostConfigurationWithHostFactory(hostFactory));
@@ -307,28 +362,54 @@ public class HttpClientFactory
return httpClient;
}
protected HttpClient getDefaultHttpClient()
protected RequestHeadersHttpClient getDefaultHttpClient()
{
return getDefaultHttpClient(host, port);
}
protected HttpClient getDefaultHttpClient(String httpHost, int httpPort)
protected RequestHeadersHttpClient getDefaultHttpClient(String httpHost, int httpPort)
{
HttpClient httpClient = constructHttpClient();
RequestHeadersHttpClient httpClient = constructHttpClient();
httpClient.getHostConfiguration().setHost(httpHost, httpPort);
return httpClient;
}
/**
* Build HTTP Client using default headers
* @return RequestHeadersHttpClient including default header for shared secret method
*/
protected RequestHeadersHttpClient constructSharedSecretHttpClient()
{
RequestHeadersHttpClient client = constructHttpClient();
client.setDefaultHeaders(Map.of(sharedSecretHeader, sharedSecret));
return client;
}
protected RequestHeadersHttpClient getSharedSecretHttpClient()
{
return getSharedSecretHttpClient(host, port);
}
protected RequestHeadersHttpClient getSharedSecretHttpClient(String httpHost, int httpPort)
{
RequestHeadersHttpClient httpClient = constructSharedSecretHttpClient();
httpClient.getHostConfiguration().setHost(httpHost, httpPort);
return httpClient;
}
protected AlfrescoHttpClient getAlfrescoHttpsClient()
{
AlfrescoHttpClient repoClient = new HttpsClient(getHttpsClient());
return repoClient;
return new HttpsClient(getHttpsClient());
}
protected AlfrescoHttpClient getAlfrescoHttpClient()
{
AlfrescoHttpClient repoClient = new DefaultHttpClient(getDefaultHttpClient());
return repoClient;
return new DefaultHttpClient(getDefaultHttpClient());
}
protected AlfrescoHttpClient getAlfrescoSharedSecretClient()
{
return new DefaultHttpClient(getSharedSecretHttpClient());
}
protected HttpClient getMD5HttpClient(String host, int port)
@@ -341,66 +422,37 @@ public class HttpClientFactory
public AlfrescoHttpClient getRepoClient(String host, int port)
{
AlfrescoHttpClient repoClient = null;
if(secureCommsType == SecureCommsType.HTTPS)
switch (secureCommsType)
{
repoClient = getAlfrescoHttpsClient();
case HTTPS: return getAlfrescoHttpsClient();
case NONE: return getAlfrescoHttpClient();
case SECRET: return getAlfrescoSharedSecretClient();
default: throw new AlfrescoRuntimeException("Invalid Solr secure communications type configured in [solr|alfresco].secureComms, should be 'ssl', 'none' or 'secret'");
}
else if(secureCommsType == SecureCommsType.NONE)
}
public RequestHeadersHttpClient getHttpClient()
{
switch (secureCommsType)
{
repoClient = getAlfrescoHttpClient();
case HTTPS: return getHttpsClient();
case NONE: return getDefaultHttpClient();
case SECRET: return getSharedSecretHttpClient();
default: throw new AlfrescoRuntimeException("Invalid Solr secure communications type configured in [solr|alfresco].secureComms, should be 'ssl', 'none' or 'secret'");
}
else
{
throw new AlfrescoRuntimeException("Invalid Solr secure communications type configured in alfresco.secureComms, should be 'ssl'or 'none'");
}
return repoClient;
}
public HttpClient getHttpClient()
public RequestHeadersHttpClient getHttpClient(String host, int port)
{
HttpClient httpClient = null;
if(secureCommsType == SecureCommsType.HTTPS)
switch (secureCommsType)
{
httpClient = getHttpsClient();
case HTTPS: return getHttpsClient(host, port);
case NONE: return getDefaultHttpClient(host, port);
case SECRET: return getSharedSecretHttpClient(host, port);
default: throw new AlfrescoRuntimeException("Invalid Solr secure communications type configured in [solr|alfresco].secureComms, should be 'ssl', 'none' or 'secret'");
}
else if(secureCommsType == SecureCommsType.NONE)
{
httpClient = getDefaultHttpClient();
}
else
{
throw new AlfrescoRuntimeException("Invalid Solr secure communications type configured in alfresco.secureComms, should be 'ssl'or 'none'");
}
return httpClient;
}
public HttpClient getHttpClient(String host, int port)
{
HttpClient httpClient = null;
if(secureCommsType == SecureCommsType.HTTPS)
{
httpClient = getHttpsClient(host, port);
}
else if(secureCommsType == SecureCommsType.NONE)
{
httpClient = getDefaultHttpClient(host, port);
}
else
{
throw new AlfrescoRuntimeException("Invalid Solr secure communications type configured in alfresco.secureComms, should be 'ssl'or 'none'");
}
return httpClient;
}
/**
* A secure client connection to the repository.
*

View File

@@ -0,0 +1,87 @@
/*
* Copyright (C) 2005-2021 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* 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/>.
*/
package org.alfresco.httpclient;
import java.io.IOException;
import java.util.Map;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
/**
* Since Apache HttpClient 3.1 doesn't support including custom headers by default,
* this class is adding that custom headers every time a method is invoked.
*/
public class RequestHeadersHttpClient extends HttpClient
{
private Map<String, String> defaultHeaders;
public RequestHeadersHttpClient(MultiThreadedHttpConnectionManager connectionManager)
{
super(connectionManager);
}
public Map<String, String> getDefaultHeaders()
{
return defaultHeaders;
}
public void setDefaultHeaders(Map<String, String> defaultHeaders)
{
this.defaultHeaders = defaultHeaders;
}
private void addDefaultHeaders(HttpMethod method)
{
if (defaultHeaders != null)
{
defaultHeaders.forEach((k,v) -> {
method.addRequestHeader(k, v);
});
}
}
@Override
public int executeMethod(HttpMethod method) throws IOException, HttpException
{
addDefaultHeaders(method);
return super.executeMethod(method);
}
@Override
public int executeMethod(HostConfiguration hostConfiguration, HttpMethod method) throws IOException, HttpException
{
addDefaultHeaders(method);
return super.executeMethod(hostConfiguration, method);
}
@Override
public int executeMethod(HostConfiguration hostconfig, HttpMethod method, HttpState state)
throws IOException, HttpException
{
addDefaultHeaders(method);
return super.executeMethod(hostconfig, method, state);
}
}

View File

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

View File

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

View File

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

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>8.301-SNAPSHOT</version>
<version>8.300.1-SNAPSHOT</version>
</parent>
<profiles>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -66,6 +66,8 @@
<bean id="SOLRAuthenticationFilter" class="org.alfresco.repo.web.scripts.solr.SOLRAuthenticationFilter">
<property name="secureComms" value="${solr.secureComms}"/>
<property name="sharedSecret" value="${solr.sharedSecret}"/>
<property name="sharedSecretHeader" value="${solr.sharedSecret.header}"/>
</bean>
<bean id="WebscriptAuthenticationFilter" class="org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory">

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>8.301-SNAPSHOT</version>
<version>8.300.3-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Alfresco Community Repo Parent</name>
@@ -15,9 +15,9 @@
<modules>
<module>core</module>
<module>data-model</module>
<module>repository</module>
<module>remote-api</module>
<module>packaging</module>
<!-- <module>repository</module>-->
<!-- <module>remote-api</module>-->
<!-- <module>packaging</module>-->
</modules>
<properties>

View File

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

View File

@@ -1,62 +1,61 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.solr;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.FilterChain;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.httpclient.HttpClientFactory;
import org.alfresco.repo.web.filter.beans.DependencyInjectedFilter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
/**
* This filter protects the solr callback urls by verifying MACs on requests and encrypting responses
* and generating MACs on responses, if the secureComms property is set to "md5". If it is set to "https"
* or "none", the filter does nothing to the request and response.
*
* This filter protects the solr callback urls by verifying a shared secret on the request header if
* the secureComms property is set to "secret". If it is set to "https", this will will just verify
* that the request came in through a "secure" tomcat connector. (but it will not validate the certificate
* on the request; this done in a different filter).
*
* @since 4.0
*
*/
public class SOLRAuthenticationFilter implements DependencyInjectedFilter
public class SOLRAuthenticationFilter implements DependencyInjectedFilter, InitializingBean
{
public static enum SecureCommsType
{
HTTPS, NONE;
HTTPS, SECRET, NONE;
public static SecureCommsType getType(String type)
{
@@ -64,6 +63,10 @@ public class SOLRAuthenticationFilter implements DependencyInjectedFilter
{
return HTTPS;
}
else if(type.equalsIgnoreCase("secret"))
{
return SECRET;
}
else if(type.equalsIgnoreCase("none"))
{
return NONE;
@@ -79,7 +82,11 @@ public class SOLRAuthenticationFilter implements DependencyInjectedFilter
private static Log logger = LogFactory.getLog(SOLRAuthenticationFilter.class);
private SecureCommsType secureComms = SecureCommsType.HTTPS;
private String sharedSecret;
private String sharedSecretHeader = HttpClientFactory.DEFAULT_SHAREDSECRET_HEADER;
public void setSecureComms(String type)
{
try
@@ -92,6 +99,33 @@ public class SOLRAuthenticationFilter implements DependencyInjectedFilter
}
}
public void setSharedSecret(String sharedSecret)
{
this.sharedSecret = sharedSecret;
}
public void setSharedSecretHeader(String sharedSecretHeader)
{
this.sharedSecretHeader = sharedSecretHeader;
}
@Override
public void afterPropertiesSet() throws Exception
{
if(secureComms == SecureCommsType.SECRET)
{
if(sharedSecret == null || sharedSecret.length()==0)
{
logger.fatal("Missing value for solr.sharedSecret configuration property. If solr.secureComms is set to \"secret\", a value for solr.sharedSecret is required. See https://docs.alfresco.com/search-services/latest/install/options/");
throw new AlfrescoRuntimeException("Missing value for solr.sharedSecret configuration property");
}
if(sharedSecretHeader == null || sharedSecretHeader.length()==0)
{
throw new AlfrescoRuntimeException("Missing value for sharedSecretHeader");
}
}
}
public void doFilter(ServletContext context, ServletRequest request,
ServletResponse response, FilterChain chain) throws IOException,
ServletException
@@ -99,52 +133,22 @@ public class SOLRAuthenticationFilter implements DependencyInjectedFilter
HttpServletRequest httpRequest = (HttpServletRequest)request;
HttpServletResponse httpResponse = (HttpServletResponse)response;
/* if(secureComms == SecureCommsType.ALFRESCO)
if(secureComms == SecureCommsType.SECRET)
{
// Need to get as a byte array because we need to read the request twice, once for authentication
// and again by the web service.
SOLRHttpServletRequestWrapper requestWrapper = new SOLRHttpServletRequestWrapper(httpRequest, encryptionUtils);
if(logger.isDebugEnabled())
if(sharedSecret.equals(httpRequest.getHeader(sharedSecretHeader)))
{
logger.debug("Authenticating " + httpRequest.getRequestURI());
}
if(encryptionUtils.authenticate(httpRequest, requestWrapper.getDecryptedBody()))
{
try
{
OutputStream out = response.getOutputStream();
GenericResponseWrapper responseWrapper = new GenericResponseWrapper(httpResponse);
// TODO - do I need to chain to other authenticating filters - probably not?
// Could also remove sending of credentials with http request
chain.doFilter(requestWrapper, responseWrapper);
Pair<byte[], AlgorithmParameters> pair = encryptor.encrypt(KeyProvider.ALIAS_SOLR, null, responseWrapper.getData());
encryptionUtils.setResponseAuthentication(httpRequest, httpResponse, responseWrapper.getData(), pair.getSecond());
httpResponse.setHeader("Content-Length", Long.toString(pair.getFirst().length));
out.write(pair.getFirst());
out.close();
}
catch(Exception e)
{
throw new AlfrescoRuntimeException("", e);
}
chain.doFilter(request, response);
}
else
{
httpResponse.setStatus(401);
httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Authentication failure");
}
}
else */if(secureComms == SecureCommsType.HTTPS)
else if(secureComms == SecureCommsType.HTTPS)
{
if(httpRequest.isSecure())
{
// https authentication
// https authentication; cert got verified in X509 filter
chain.doFilter(request, response);
}
else
@@ -158,128 +162,4 @@ public class SOLRAuthenticationFilter implements DependencyInjectedFilter
}
}
protected boolean validateTimestamp(String timestampStr)
{
if(timestampStr == null || timestampStr.equals(""))
{
throw new AlfrescoRuntimeException("Missing timestamp on request");
}
long timestamp = -1;
try
{
timestamp = Long.valueOf(timestampStr);
}
catch(NumberFormatException e)
{
throw new AlfrescoRuntimeException("Invalid timestamp on request");
}
if(timestamp == -1)
{
throw new AlfrescoRuntimeException("Invalid timestamp on request");
}
long currentTime = System.currentTimeMillis();
return((currentTime - timestamp) < 30 * 1000); // 5s
}
/* private static class SOLRHttpServletRequestWrapper extends HttpServletRequestWrapper
{
private byte[] body;
SOLRHttpServletRequestWrapper(HttpServletRequest req, EncryptionUtils encryptionUtils) throws IOException
{
super(req);
this.body = encryptionUtils.decryptBody(req);
}
byte[] getDecryptedBody()
{
return body;
}
public ServletInputStream getInputStream()
{
final InputStream in = (body != null ? new ByteArrayInputStream(body) : null);
return new ServletInputStream()
{
public int read() throws IOException
{
if(in == null)
{
return -1;
}
else
{
int i = in.read();
if(i == -1)
{
in.close();
}
return i;
}
}
};
}
}*/
private static class ByteArrayServletOutputStream extends ServletOutputStream
{
private ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayServletOutputStream()
{
}
public byte[] getData()
{
return out.toByteArray();
}
@Override
public void write(int b) throws IOException
{
out.write(b);
}
}
public static class GenericResponseWrapper extends HttpServletResponseWrapper {
private ByteArrayServletOutputStream output;
private int contentLength;
private String contentType;
public GenericResponseWrapper(HttpServletResponse response) {
super(response);
output = new ByteArrayServletOutputStream();
}
public byte[] getData() {
return output.getData();
}
public ServletOutputStream getOutputStream() {
return output;
}
public PrintWriter getWriter() {
return new PrintWriter(getOutputStream(),true);
}
public void setContentLength(int length) {
this.contentLength = length;
super.setContentLength(length);
}
public int getContentLength() {
return contentLength;
}
public void setContentType(String type) {
this.contentType = type;
super.setContentType(type);
}
public String getContentType() {
return contentType;
}
}
}

View File

@@ -31,6 +31,7 @@ import java.util.Properties;
import javax.servlet.ServletContext;
import org.alfresco.httpclient.HttpClientFactory.SecureCommsType;
import org.alfresco.web.scripts.servlet.X509ServletFilterBase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -70,7 +71,9 @@ public class AlfrescoX509ServletFilter extends X509ServletFilterBase
* Return true or false based on the property. This will switch on/off X509 enforcement in the X509ServletFilterBase.
*/
if (prop == null || "none".equals(prop))
if (prop == null ||
SecureCommsType.getType(prop) == SecureCommsType.NONE ||
SecureCommsType.getType(prop) == SecureCommsType.SECRET)
{
return false;
}

View File

@@ -66,6 +66,8 @@
<bean id="SOLRAuthenticationFilter" class="org.alfresco.repo.web.scripts.solr.SOLRAuthenticationFilter">
<property name="secureComms" value="${solr.secureComms}"/>
<property name="sharedSecret" value="${solr.sharedSecret}"/>
<property name="sharedSecretHeader" value="${solr.sharedSecret.header}"/>
</bean>
<bean id="WebscriptAuthenticationFilter" class="org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory">

View File

@@ -39,6 +39,7 @@ import org.junit.runners.Suite;
org.alfresco.repo.web.scripts.workflow.WorkflowModelBuilderTest.class,
org.alfresco.repo.web.scripts.solr.StatsGetTest.class,
org.alfresco.repo.web.scripts.solr.SOLRSerializerTest.class,
org.alfresco.repo.web.scripts.solr.SOLRAuthenticationFilterTest.class,
org.alfresco.repo.web.util.PagingCursorTest.class,
org.alfresco.repo.web.util.paging.PagingTest.class,
org.alfresco.repo.webdav.GetMethodTest.class,

View File

@@ -0,0 +1,176 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2021 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.solr;
import org.alfresco.error.AlfrescoRuntimeException;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import javax.servlet.FilterChain;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import static org.junit.Assert.assertEquals;
public class SOLRAuthenticationFilterTest
{
@Test(expected = AlfrescoRuntimeException.class)
public void testSharedSecretNotConfigured() throws Exception
{
SOLRAuthenticationFilter filter = new SOLRAuthenticationFilter();
filter.setSecureComms(SOLRAuthenticationFilter.SecureCommsType.SECRET.name());
filter.afterPropertiesSet();
}
@Test(expected = AlfrescoRuntimeException.class)
public void testSharedHeaderNotConfigured() throws Exception
{
SOLRAuthenticationFilter filter = new SOLRAuthenticationFilter();
filter.setSecureComms(SOLRAuthenticationFilter.SecureCommsType.SECRET.name());
filter.setSharedSecret("shared-secret");
filter.setSharedSecretHeader("");
filter.afterPropertiesSet();
}
@Test
public void testHTTPSFilterAndSharedSecretSet() throws Exception
{
String headerKey = "test-header";
String sharedSecret = "shared-secret";
SOLRAuthenticationFilter filter = new SOLRAuthenticationFilter();
filter.setSecureComms(SOLRAuthenticationFilter.SecureCommsType.HTTPS.name());
filter.setSharedSecret(sharedSecret);
filter.setSharedSecretHeader(headerKey);
filter.afterPropertiesSet();
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
Mockito.when(request.getHeader(headerKey)).thenReturn(sharedSecret);
Mockito.when(request.isSecure()).thenReturn(true);
FilterChain chain = Mockito.mock(FilterChain.class);
filter.doFilter(Mockito.mock(ServletContext.class), request, response, chain);
Mockito.verify(chain, Mockito.times(1)).doFilter(request, response);
}
@Test(expected = AlfrescoRuntimeException.class)
public void testHTTPSFilterAndInsecureRequest() throws Exception
{
SOLRAuthenticationFilter filter = new SOLRAuthenticationFilter();
filter.setSecureComms(SOLRAuthenticationFilter.SecureCommsType.HTTPS.name());
filter.afterPropertiesSet();
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
Mockito.when(request.isSecure()).thenReturn(false);
FilterChain chain = Mockito.mock(FilterChain.class);
filter.doFilter(Mockito.mock(ServletContext.class), request, response, chain);
}
@Test
public void testNoAuthentication() throws Exception
{
SOLRAuthenticationFilter filter = new SOLRAuthenticationFilter();
filter.setSecureComms(SOLRAuthenticationFilter.SecureCommsType.NONE.name());
filter.afterPropertiesSet();
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
FilterChain chain = Mockito.mock(FilterChain.class);
filter.doFilter(Mockito.mock(ServletContext.class), request, response, chain);
Mockito.verify(chain, Mockito.times(1)).doFilter(request, response);
}
@Test
public void testSharedSecretFilter() throws Exception
{
String headerKey = "test-header";
String sharedSecret = "shared-secret";
SOLRAuthenticationFilter filter = new SOLRAuthenticationFilter();
filter.setSecureComms(SOLRAuthenticationFilter.SecureCommsType.SECRET.name());
filter.setSharedSecret(sharedSecret);
filter.setSharedSecretHeader(headerKey);
filter.afterPropertiesSet();
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
Mockito.when(request.getHeader(headerKey)).thenReturn(sharedSecret);
FilterChain chain = Mockito.mock(FilterChain.class);
filter.doFilter(Mockito.mock(ServletContext.class), request, response, chain);
Mockito.verify(chain, Mockito.times(1)).doFilter(request, response);
}
@Test
public void testSharedSecretDontMatch() throws Exception
{
String headerKey = "test-header";
String sharedSecret = "shared-secret";
SOLRAuthenticationFilter filter = new SOLRAuthenticationFilter();
filter.setSecureComms(SOLRAuthenticationFilter.SecureCommsType.SECRET.name());
filter.setSharedSecret(sharedSecret);
filter.setSharedSecretHeader(headerKey);
filter.afterPropertiesSet();
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
Mockito.when(request.getHeader(headerKey)).thenReturn("wrong-secret");
FilterChain chain = Mockito.mock(FilterChain.class);
filter.doFilter(Mockito.mock(ServletContext.class), request, response, chain);
Mockito.verify(chain, Mockito.times(0)).doFilter(request, response);
Mockito.verify(response).sendError(Mockito.eq(HttpServletResponse.SC_FORBIDDEN), Mockito.anyString());
}
@Test
public void testSharedHeaderNotPresent() throws Exception
{
String headerKey = "test-header";
String sharedSecret = "shared-secret";
SOLRAuthenticationFilter filter = new SOLRAuthenticationFilter();
filter.setSecureComms(SOLRAuthenticationFilter.SecureCommsType.SECRET.name());
filter.setSharedSecret(sharedSecret);
filter.setSharedSecretHeader(headerKey);
filter.afterPropertiesSet();
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
FilterChain chain = Mockito.mock(FilterChain.class);
filter.doFilter(Mockito.mock(ServletContext.class), request, response, chain);
Mockito.verify(chain, Mockito.times(0)).doFilter(request, response);
Mockito.verify(response).sendError(Mockito.eq(HttpServletResponse.SC_FORBIDDEN), Mockito.anyString());
}
}

View File

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

View File

@@ -864,6 +864,8 @@ solr.solrUser=solr
solr.solrPassword=solr
# none, https
solr.secureComms=https
solr.sharedSecret=
solr.sharedSecret.header=X-Alfresco-Search-Secret
solr.cmis.alternativeDictionary=DEFAULT_DICTIONARY
solr.max.total.connections=40

View File

@@ -161,6 +161,8 @@
<property name="keyResourceLoader" ref="springKeyResourceLoader"/>
<property name="keyStoreParameters" ref="keyStoreParameters"/>
<property name="encryptionParameters" ref="md5EncryptionParameters"/>
<property name="sharedSecret" value="${solr.sharedSecret}"/>
<property name="sharedSecretHeader" value="${solr.sharedSecret.header}"/>
<property name="host" value="${solr.host}"/>
<property name="port" value="${solr.port}"/>
<property name="sslPort" value="${solr.port.ssl}"/>

View File

@@ -31,14 +31,16 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import java.io.UnsupportedEncodingException;
import org.alfresco.httpclient.HttpClientFactory;
import org.alfresco.httpclient.RequestHeadersHttpClient;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.util.Pair;
import org.apache.commons.codec.net.URLCodec;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -46,8 +48,6 @@ import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.beans.factory.BeanFactory;
import java.io.UnsupportedEncodingException;
/**
* @author Andy
*
@@ -64,34 +64,34 @@ public class SolrStoreMappingWrapperTest
HttpClientFactory httpClientFactory;
@Mock
HttpClient httpClientCommon;
RequestHeadersHttpClient httpClientCommon;
@Mock
HttpClient httpClient1;
RequestHeadersHttpClient httpClient1;
@Mock
HttpClient httpClient2;
RequestHeadersHttpClient httpClient2;
@Mock
HttpClient httpClient3;
RequestHeadersHttpClient httpClient3;
@Mock
HttpClient httpClient4;
RequestHeadersHttpClient httpClient4;
@Mock
HttpClient httpClient5;
RequestHeadersHttpClient httpClient5;
@Mock
HttpClient httpClient6;
RequestHeadersHttpClient httpClient6;
@Mock
HttpClient httpClient7;
RequestHeadersHttpClient httpClient7;
@Mock
HttpClient httpClient8;
RequestHeadersHttpClient httpClient8;
@Mock
HttpClient httpClient9;
RequestHeadersHttpClient httpClient9;
@Mock
HostConfiguration hostConfigurationCommon;