mirror of
https://github.com/Alfresco/SearchServices.git
synced 2025-09-10 14:11:25 +00:00
SEARCH-2802: Search Services to support for Shared Secret communication.
This commit is contained in:
@@ -17,10 +17,10 @@ $ tree generators/app/templates/
|
||||
│ ├── .env
|
||||
│ ├── docker-compose-ce.yml
|
||||
│ └── docker-compose-ee.yml
|
||||
├── latest
|
||||
├── 7.0
|
||||
│ ├── .env
|
||||
│ ├── docker-compose-ce.yml
|
||||
│ └── docker-compose-ee.yml├── empty
|
||||
│ └── docker-compose-ee.yml
|
||||
├── images
|
||||
│ ├── alfresco
|
||||
│ │ ├── Dockerfile
|
||||
@@ -82,7 +82,7 @@ $ yo alfresco-docker-compose
|
||||
|
||||
## ACS Version
|
||||
|
||||
Currently supported ACS Versions are `latest`, `6.2` and `6.1`
|
||||
Currently supported ACS Versions are `7.0`, `6.2` and `6.1`
|
||||
|
||||
This is the first choice to be selected when the generator is executed.
|
||||
|
||||
@@ -90,7 +90,7 @@ This is the first choice to be selected when the generator is executed.
|
||||
? Which ACS version do you want to use?
|
||||
6.1
|
||||
6.2
|
||||
❯ latest
|
||||
❯ 7.0
|
||||
```
|
||||
|
||||
## AGS Version
|
||||
@@ -107,14 +107,15 @@ If you chose ACS 6.1, a prompt will allow you to use AGS.
|
||||
|
||||
When using Community, some different options can be combined:
|
||||
|
||||
* Plain HTTP (http) or TLS/SSL Mutual Authentication (https) for communication between Alfresco and SOLR
|
||||
* Plain HTTP (http) or HTTPs (https) for Http Web Proxy for HTTP access to services
|
||||
* Protect the access to SOLR REST API in the Http WebProxy to forbid direct access to Alfresco Web Proxy port
|
||||
* Use SOLR Replication in Master/Slave mode (only when using http)
|
||||
* Plain HTTP (http), Shared Secret HTTP (secret) or TLS/SSL Mutual Authentication (https) for communication between Alfresco and SOLR
|
||||
>> Shared Secret is only available from ACS 7.0.1
|
||||
|
||||
```
|
||||
? Would you like to use Alfresco enterprise or community? community
|
||||
? Would you like to use HTTP or mTLS for Alfresco-SOLR communication? http
|
||||
? Would you like to use HTTP, Shared Secret or mTLS for Alfresco-SOLR communication? http
|
||||
? Would you like to use HTTP or HTTPs for Web Proxy? http
|
||||
? Would you like to protect the access to SOLR REST API? Yes
|
||||
? Would you like to use a SOLR Replication? No
|
||||
|
@@ -21,8 +21,8 @@ module.exports = class extends Generator {
|
||||
type: 'list',
|
||||
name: 'acsVersion',
|
||||
message: 'Which ACS version do you want to use?',
|
||||
choices: [ '6.1', '6.2', 'latest' ],
|
||||
default: 'latest'
|
||||
choices: [ '6.1', '6.2', '7.0' ],
|
||||
default: '7.0'
|
||||
},
|
||||
{
|
||||
whenFunction: response => response.acsVersion == '6.1',
|
||||
@@ -41,8 +41,8 @@ module.exports = class extends Generator {
|
||||
{
|
||||
type: 'list',
|
||||
name: 'httpMode',
|
||||
message: 'Would you like to use HTTP or mTLS for Alfresco-SOLR communication?',
|
||||
choices: [ "http", "https" ],
|
||||
message: 'Would you like to use HTTP, Shared Secret or mTLS for Alfresco-SOLR communication?',
|
||||
choices: [ "http", "https", "secret" ],
|
||||
default: 'http'
|
||||
},
|
||||
{
|
||||
@@ -156,7 +156,7 @@ module.exports = class extends Generator {
|
||||
// Generate boilerplate from "templates" folder
|
||||
writing() {
|
||||
|
||||
// Set base template directory: 6.1, 6.2, latest
|
||||
// Set base template directory: 6.1, 6.2, 7.0
|
||||
var dockerComposeTemplateDirectory = this.props.acsVersion;
|
||||
|
||||
// Docker Compose environment variables values
|
||||
@@ -183,7 +183,7 @@ module.exports = class extends Generator {
|
||||
'alfresco/alfresco-content-repository-community') :
|
||||
(this.props.ags ?
|
||||
'quay.io/alfresco/alfresco-governance-repository-enterprise':
|
||||
'alfresco/alfresco-content-repository'
|
||||
'quay.io/alfresco/alfresco-content-repository'
|
||||
)
|
||||
);
|
||||
|
||||
@@ -192,7 +192,7 @@ module.exports = class extends Generator {
|
||||
(this.props.alfrescoVersion == 'community' ?
|
||||
(this.props.ags ?
|
||||
'alfresco/alfresco-governance-share-community' :
|
||||
'quay.io/alfresco/alfresco-share') :
|
||||
'alfresco/alfresco-share') :
|
||||
(this.props.ags ?
|
||||
'quay.io/alfresco/alfresco-governance-share-enterprise':
|
||||
'quay.io/alfresco/alfresco-share'
|
||||
@@ -219,8 +219,8 @@ module.exports = class extends Generator {
|
||||
httpMode: this.props.httpMode,
|
||||
httpWebMode: this.props.httpWebMode,
|
||||
port: (this.props.httpWebMode == 'http' ? '8080' : '443'),
|
||||
secureComms: (this.props.httpMode == 'http' ? 'none' : 'https'),
|
||||
alfrescoPort: (this.props.httpMode == 'http' ? '8080' : '8443'),
|
||||
secureComms: (this.props.httpMode == 'http' ? 'none' : this.props.httpMode),
|
||||
alfrescoPort: (this.props.httpMode == 'https' ? '8443' : '8080'),
|
||||
replication: this.props.replication,
|
||||
searchSolrHost: (this.props.replication ? "solr6secondary" : "solr6"),
|
||||
searchPath: searchBasePath,
|
||||
@@ -279,7 +279,7 @@ module.exports = class extends Generator {
|
||||
)
|
||||
}
|
||||
|
||||
// Empty addons directories.
|
||||
// Empty addons directories
|
||||
['alfresco', 'share'].forEach(container => {
|
||||
['jars', 'amps'].forEach(addonType => {
|
||||
this.fs.copy(
|
||||
|
13
e2e-test/generator-alfresco-docker-compose/generators/app/templates/7.0/.env
Executable file
13
e2e-test/generator-alfresco-docker-compose/generators/app/templates/7.0/.env
Executable file
@@ -0,0 +1,13 @@
|
||||
ALFRESCO_TAG=7.0.0
|
||||
ALFRESCO_CE_TAG=7.0.0
|
||||
SHARE_TAG=7.0.0
|
||||
POSTGRES_TAG=13.1
|
||||
TRANSFORM_CORE_AIO_TAG=2.3.10
|
||||
TRANSFORM_ROUTER_TAG=1.3.2
|
||||
SHARED_FILE_STORE_TAG=0.13.0
|
||||
ACTIVE_MQ_TAG=5.16.1
|
||||
DIGITAL_WORKSPACE_TAG=2.1.0-adw
|
||||
ACS_NGINX_TAG=3.1.1
|
||||
SEARCH_TAG=latest
|
||||
ZEPPELIN_TAG=latest
|
||||
ACA_TAG=2.3.0
|
@@ -14,8 +14,21 @@ services:
|
||||
KEYSTORE_TYPE: JCEKS
|
||||
KEYSTORE_PASS: kT9X6oe68t <% } %>
|
||||
COMPRESS_CONTENT: "<%=gzip%>"
|
||||
SHARE_SERVICES_TAG: ${SHARE_TAG}
|
||||
mem_limit: 1800m
|
||||
depends_on:
|
||||
- postgres
|
||||
environment:
|
||||
JAVA_TOOL_OPTIONS: "
|
||||
-Dencryption.keystore.type=JCEKS
|
||||
-Dencryption.cipherAlgorithm=DESede/CBC/PKCS5Padding
|
||||
-Dencryption.keyAlgorithm=DESede
|
||||
-Dencryption.keystore.location=/usr/local/tomcat/shared/classes/alfresco/extension/keystore/keystore
|
||||
-Dmetadata-keystore.password=mp6yc0UD9e
|
||||
-Dmetadata-keystore.aliases=metadata
|
||||
-Dmetadata-keystore.metadata.password=oKIWzVdEdA
|
||||
-Dmetadata-keystore.metadata.algorithm=DESede
|
||||
"
|
||||
JAVA_OPTS : "
|
||||
-Ddb.driver=org.postgresql.Driver
|
||||
-Ddb.username=alfresco
|
||||
@@ -25,20 +38,19 @@ services:
|
||||
-Dsolr.port.ssl=8983
|
||||
-Dsolr.secureComms=<%=secureComms%>
|
||||
-Dsolr.baseUrl=/solr
|
||||
-Dindex.subsystem.name=solr6
|
||||
-Dindex.subsystem.name=solr6<% if (httpMode == 'secret') { %>
|
||||
-Dsolr.sharedSecret=secret<% } %>
|
||||
-Dshare.host=localhost
|
||||
-Dalfresco.port=8080
|
||||
-Daos.baseUrlOverwrite=http://localhost:8080/alfresco/aos
|
||||
-Dmessaging.broker.url=\"failover:(nio://activemq:61616)?timeout=3000&jms.useCompression=true\"
|
||||
-Ddeployment.method=DOCKER_COMPOSE
|
||||
|
||||
-DlocalTransform.core-aio.url=http://transform-core-aio:8090/
|
||||
-Dalfresco-pdf-renderer.url=http://transform-core-aio:8090/
|
||||
-Djodconverter.url=http://transform-core-aio:8090/
|
||||
-Dimg.url=http://transform-core-aio:8090/
|
||||
-Dtika.url=http://transform-core-aio:8090/
|
||||
-Dtransform.misc.url=http://transform-core-aio:8090/
|
||||
|
||||
-Dcsrf.filter.enabled=false
|
||||
-Dalfresco.restApi.basicAuthScheme=true
|
||||
-Xms1500m -Xmx1500m
|
||||
@@ -63,6 +75,8 @@ services:
|
||||
COMPRESS_CONTENT: "<%=gzip%>"
|
||||
SEARCH_LOG_LEVEL: <%=searchLogLevel%>
|
||||
mem_limit: 1200m
|
||||
depends_on:
|
||||
- alfresco
|
||||
environment:
|
||||
#Solr needs to know how to register itself with Alfresco
|
||||
SOLR_ALFRESCO_HOST: "alfresco"
|
||||
@@ -84,6 +98,9 @@ services:
|
||||
SOLR_OPTS: "
|
||||
-Dsolr.ssl.checkPeerName=false
|
||||
-Dsolr.allow.unsafe.resourceloading=true
|
||||
" <% } %> <% if (httpMode == 'secret') { %>
|
||||
SOLR_OPTS: "
|
||||
-Dalfresco.secureComms.secret=secret
|
||||
" <% } %>
|
||||
ports:
|
||||
- 8083:8983 <% if (httpMode == 'https') { %>
|
||||
@@ -106,6 +123,8 @@ services:
|
||||
MASTER_HOST: solr6 <% } %>
|
||||
COMPRESS_CONTENT: "<%=gzip%>"
|
||||
mem_limit: 1200m
|
||||
depends_on:
|
||||
- alfresco
|
||||
environment:
|
||||
#Solr needs to know how to register itself with Alfresco
|
||||
SOLR_ALFRESCO_HOST: "alfresco"
|
||||
@@ -127,6 +146,9 @@ services:
|
||||
SOLR_OPTS: "
|
||||
-Dsolr.ssl.checkPeerName=false
|
||||
-Dsolr.allow.unsafe.resourceloading=true
|
||||
" <% } %> <% if (httpMode == 'secret') { %>
|
||||
SOLR_OPTS: "
|
||||
-Dalfresco.secureComms.secret=secret
|
||||
" <% } %>
|
||||
ports:
|
||||
- 8084:8983 <% if (httpMode == 'https') { %>
|
||||
@@ -193,6 +215,9 @@ services:
|
||||
mem_limit: 128m
|
||||
depends_on:
|
||||
- alfresco
|
||||
- share
|
||||
- solr6
|
||||
- content-app
|
||||
volumes:
|
||||
- ./config/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./config/nginx.htpasswd:/etc/nginx/conf.d/nginx.htpasswd <% if (httpWebMode == 'https') { %>
|
@@ -13,17 +13,19 @@ services:
|
||||
KEYSTORE_TYPE: JCEKS
|
||||
KEYSTORE_PASS: kT9X6oe68t <% } %>
|
||||
COMPRESS_CONTENT: "<%=gzip%>"
|
||||
SHARE_SERVICES_TAG: ${SHARE_TAG}
|
||||
mem_limit: 1800m
|
||||
environment:
|
||||
JAVA_TOOL_OPTIONS: "
|
||||
-Dencryption.keystore.type=JCEKS
|
||||
-Dencryption.cipherAlgorithm=DESede/CBC/PKCS5Padding
|
||||
-Dencryption.keyAlgorithm=DESede
|
||||
-Dencryption.keystore.location=/usr/local/tomcat/shared/classes/alfresco/extension/keystore/keystore
|
||||
-Dmetadata-keystore.password=mp6yc0UD9e
|
||||
-Dmetadata-keystore.aliases=metadata
|
||||
-Dmetadata-keystore.metadata.password=mp6yc0UD9e
|
||||
-Dmetadata-keystore.metadata.algorithm=AES
|
||||
-Dmetadata-keystore.metadata.password=oKIWzVdEdA
|
||||
-Dmetadata-keystore.metadata.algorithm=DESede
|
||||
<% if (httpMode == 'https') { %>
|
||||
-Dencryption.keystore.type=pkcs12
|
||||
-Dencryption.cipherAlgorithm=AES/CBC/PKCS5Padding
|
||||
-Dencryption.keyAlgorithm=AES
|
||||
-Dssl-keystore.password=kT9X6oe68t
|
||||
-Dssl-keystore.aliases=ssl-alfresco-ca,ssl-repo
|
||||
-Dssl-keystore.ssl-alfresco-ca.password=kT9X6oe68t
|
||||
@@ -43,12 +45,11 @@ services:
|
||||
-Dsolr.secureComms=<%=secureComms%>
|
||||
-Dsolr.baseUrl=/solr <% if (sharding == 'true') { %>
|
||||
-Dsolr.useDynamicShardRegistration=true <% } %>
|
||||
-Dindex.subsystem.name=solr6
|
||||
|
||||
-Dindex.subsystem.name=solr6<% if (httpMode == 'secret') { %>
|
||||
-Dsolr.sharedSecret=secret<% } %>
|
||||
-Daos.baseUrlOverwrite=http://localhost:8080/alfresco/aos
|
||||
-Dmessaging.broker.url=\"failover:(nio://activemq:61616)?timeout=3000&jms.useCompression=true\"
|
||||
-Ddeployment.method=DOCKER_COMPOSE
|
||||
|
||||
-Dtransform.service.enabled=true
|
||||
-Dtransform.service.url=http://transform-router:8095
|
||||
-Dsfs.url=http://shared-file-store:8099/
|
||||
@@ -58,7 +59,6 @@ services:
|
||||
-Dimg.url=http://transform-core-aio:8090/
|
||||
-Dtika.url=http://transform-core-aio:8090/
|
||||
-Dtransform.misc.url=http://transform-core-aio:8090/
|
||||
|
||||
-Dcsrf.filter.enabled=false
|
||||
-Dalfresco.restApi.basicAuthScheme=true
|
||||
-Xms1500m -Xmx1500m
|
||||
@@ -104,33 +104,19 @@ services:
|
||||
#Create the default alfresco and archive cores
|
||||
SOLR_CREATE_ALFRESCO_DEFAULTS: "alfresco,archive"
|
||||
SOLR_JAVA_MEM: "-Xms1g -Xmx1g" <% if (httpMode == 'https') { %>
|
||||
SOLR_SSL_TRUST_STORE: "/opt/<%=searchPath%>/keystore/ssl-repo-client.truststore"
|
||||
SOLR_SSL_TRUST_STORE: "/opt/<%=searchPath%>/keystore/ssl.repo.client.truststore"
|
||||
SOLR_SSL_TRUST_STORE_PASSWORD: "kT9X6oe68t"
|
||||
SOLR_SSL_TRUST_STORE_TYPE: "JCEKS"
|
||||
SOLR_SSL_KEY_STORE: "/opt/<%=searchPath%>/keystore/ssl-repo-client.keystore"
|
||||
SOLR_SSL_KEY_STORE: "/opt/<%=searchPath%>/keystore/ssl.repo.client.keystore"
|
||||
SOLR_SSL_KEY_STORE_PASSWORD: "kT9X6oe68t"
|
||||
SOLR_SSL_KEY_STORE_TYPE: "JCEKS"
|
||||
SOLR_SSL_NEED_CLIENT_AUTH: "true" <% if (sharding == 'true') { %>
|
||||
SOLR_SSL_CLIENT_KEY_STORE: "/opt/<%=searchPath%>/keystore/ssl-repo-client.keystore"
|
||||
SOLR_SSL_CLIENT_KEY_STORE_TYPE: "JCEKS"
|
||||
SOLR_SSL_CLIENT_TRUST_STORE: "/opt/<%=searchPath%>/keystore/ssl-repo-client.keystore"
|
||||
SOLR_SSL_CLIENT_TRUST_STORE_TYPE: "JCEKS" <% } %>
|
||||
JAVA_TOOL_OPTIONS: "
|
||||
-Dsolr.jetty.truststore.password=kT9X6oe68t
|
||||
-Dsolr.jetty.keystore.password=kT9X6oe68t <% if (sharding == 'true') { %>
|
||||
-Djavax.net.ssl.keyStorePassword=kT9X6oe68t
|
||||
-Djavax.net.ssl.trustStorePassword=kT9X6oe68t <% } %>
|
||||
-Dssl-keystore.password=kT9X6oe68t
|
||||
-Dssl-keystore.aliases=ssl-alfresco-ca,ssl-repo-client
|
||||
-Dssl-keystore.ssl-alfresco-ca.password=kT9X6oe68t
|
||||
-Dssl-keystore.ssl-repo-client.password=kT9X6oe68t
|
||||
-Dssl-truststore.password=kT9X6oe68t
|
||||
-Dssl-truststore.aliases=ssl-alfresco-ca,ssl-repo,ssl-repo-client
|
||||
-Dssl-truststore.ssl-alfresco-ca.password=kT9X6oe68t
|
||||
-Dssl-truststore.ssl-repo.password=kT9X6oe68t
|
||||
-Dssl-truststore.ssl-repo-client.password=kT9X6oe68t
|
||||
"
|
||||
SOLR_SSL_NEED_CLIENT_AUTH: "true"
|
||||
SOLR_OPTS: "
|
||||
-Dsolr.ssl.checkPeerName=false
|
||||
-Dsolr.allow.unsafe.resourceloading=true
|
||||
" <% } %> <% if (httpMode == 'secret') { %>
|
||||
SOLR_OPTS: "
|
||||
-Dalfresco.secureComms.secret=secret
|
||||
" <% } %>
|
||||
ports:
|
||||
- 8083:8983 <% if (httpMode == 'https') { %>
|
||||
@@ -169,41 +155,27 @@ services:
|
||||
SOLR_ALFRESCO_PORT: "<%=alfrescoPort%>"
|
||||
ALFRESCO_SECURE_COMMS: <%=secureComms%>
|
||||
#Alfresco needs to know how to call solr
|
||||
SOLR_SOLR_HOST: "solr6secondary"
|
||||
SOLR_SOLR_HOST: "solr6"
|
||||
SOLR_SOLR_PORT: "8983"
|
||||
#Create the default alfresco and archive cores
|
||||
SOLR_CREATE_ALFRESCO_DEFAULTS: "alfresco,archive"
|
||||
SOLR_JAVA_MEM: "-Xms1g -Xmx1g" <% if (httpMode == 'https') { %>
|
||||
SOLR_SSL_TRUST_STORE: "/opt/<%=searchPath%>/keystore/ssl-repo-client.truststore"
|
||||
SOLR_SSL_TRUST_STORE: "/opt/<%=searchPath%>/keystore/ssl.repo.client.truststore"
|
||||
SOLR_SSL_TRUST_STORE_PASSWORD: "kT9X6oe68t"
|
||||
SOLR_SSL_TRUST_STORE_TYPE: "JCEKS"
|
||||
SOLR_SSL_KEY_STORE: "/opt/<%=searchPath%>/keystore/ssl-repo-client.keystore"
|
||||
SOLR_SSL_KEY_STORE: "/opt/<%=searchPath%>/keystore/ssl.repo.client.keystore"
|
||||
SOLR_SSL_KEY_STORE_PASSWORD: "kT9X6oe68t"
|
||||
SOLR_SSL_KEY_STORE_TYPE: "JCEKS"
|
||||
SOLR_SSL_NEED_CLIENT_AUTH: "true" <% if (sharding == 'true') { %>
|
||||
SOLR_SSL_CLIENT_KEY_STORE: "/opt/<%=searchPath%>/keystore/ssl-repo-client.keystore"
|
||||
SOLR_SSL_CLIENT_KEY_STORE_TYPE: "JCEKS"
|
||||
SOLR_SSL_CLIENT_TRUST_STORE: "/opt/<%=searchPath%>/keystore/ssl-repo-client.keystore"
|
||||
SOLR_SSL_CLIENT_TRUST_STORE_TYPE: "JCEKS" <% } %>
|
||||
JAVA_TOOL_OPTIONS: "
|
||||
-Dsolr.jetty.truststore.password=kT9X6oe68t
|
||||
-Dsolr.jetty.keystore.password=kT9X6oe68t <% if (sharding == 'true') { %>
|
||||
-Djavax.net.ssl.keyStorePassword=kT9X6oe68t
|
||||
-Djavax.net.ssl.trustStorePassword=kT9X6oe68t <% } %>
|
||||
-Dssl-keystore.password=kT9X6oe68t
|
||||
-Dssl-keystore.aliases=ssl-alfresco-ca,ssl-repo-client
|
||||
-Dssl-keystore.ssl-alfresco-ca.password=kT9X6oe68t
|
||||
-Dssl-keystore.ssl-repo-client.password=kT9X6oe68t
|
||||
-Dssl-truststore.password=kT9X6oe68t
|
||||
-Dssl-truststore.aliases=ssl-alfresco-ca,ssl-repo,ssl-repo-client
|
||||
-Dssl-truststore.ssl-alfresco-ca.password=kT9X6oe68t
|
||||
-Dssl-truststore.ssl-repo.password=kT9X6oe68t
|
||||
-Dssl-truststore.ssl-repo-client.password=kT9X6oe68t
|
||||
"
|
||||
SOLR_SSL_NEED_CLIENT_AUTH: "true"
|
||||
SOLR_OPTS: "
|
||||
-Dsolr.ssl.checkPeerName=false
|
||||
-Dsolr.allow.unsafe.resourceloading=true
|
||||
" <% } %> <% if (httpMode == 'secret') { %>
|
||||
SOLR_OPTS: "
|
||||
-Dalfresco.secureComms.secret=secret
|
||||
" <% } %>
|
||||
ports:
|
||||
- 8084:8983 <% if (httpMode == 'https') { %>
|
||||
- 8083:8983 <% if (httpMode == 'https') { %>
|
||||
volumes:
|
||||
- ./keystores/solr:/opt/<%=searchPath%>/keystore <% } %>
|
||||
<% } %>
|
@@ -25,6 +25,19 @@ VOLUME ["${ALF_DATA_DIR}/keystore"]
|
||||
|
||||
USER root
|
||||
|
||||
ARG SHARE_SERVICES_TAG
|
||||
ENV SHARE_SERVICES_TAG $SHARE_SERVICES_TAG
|
||||
|
||||
# From Alfresco Repository 7.0.0 Share Services AMP is not provided with default Docker Image
|
||||
RUN if [ ! -z "$SHARE_SERVICES_TAG" ] ; then \
|
||||
yum -y update && \
|
||||
yum -y install wget && \
|
||||
yum clean all && \
|
||||
mkdir -p $TOMCAT_DIR/amps && \
|
||||
wget https://nexus.alfresco.com/nexus/service/local/repo_groups/public/content/org/alfresco/alfresco-share-services/${SHARE_SERVICES_TAG}/alfresco-share-services-${SHARE_SERVICES_TAG}.amp \
|
||||
-O $TOMCAT_DIR/amps/alfresco-share-services-${SHARE_SERVICES_TAG}.amp; \
|
||||
fi
|
||||
|
||||
# Install modules and addons
|
||||
RUN mkdir -p $TOMCAT_DIR/amps
|
||||
COPY modules/amps/* $TOMCAT_DIR/amps/
|
||||
|
@@ -21,6 +21,9 @@ ENV ALFRESCO_COMMS $ALFRESCO_COMMS
|
||||
RUN if [ "$ALFRESCO_COMMS" == "https" ] ; then \
|
||||
sed -i '/^bash.*/i sed -i "'"s/alfresco.secureComms=none/alfresco.secureComms=https/g"'" ${DIST_DIR}/solrhome/templates/rerank/conf/solrcore.properties\n' \
|
||||
${DIST_DIR}/solr/bin/search_config_setup.sh; \
|
||||
elif [ "$ALFRESCO_COMMS" == "secret" ] ; then \
|
||||
sed -i '/^bash.*/i sed -i "'"s/alfresco.secureComms=https/alfresco.secureComms=secret/g"'" ${DIST_DIR}/solrhome/templates/rerank/conf/solrcore.properties\n' \
|
||||
${DIST_DIR}/solr/bin/search_config_setup.sh; \
|
||||
else \
|
||||
sed -i '/^bash.*/i sed -i "'"s/alfresco.secureComms=https/alfresco.secureComms=none/g"'" ${DIST_DIR}/solrhome/templates/rerank/conf/solrcore.properties\n' \
|
||||
${DIST_DIR}/solr/bin/search_config_setup.sh; \
|
||||
|
@@ -1,14 +0,0 @@
|
||||
ALFRESCO_TAG=6.3.0-A10
|
||||
ALFRESCO_CE_TAG=latest
|
||||
SHARE_TAG=latest
|
||||
POSTGRES_TAG=11.4
|
||||
TRANSFORM_ROUTER_TAG=1.2.0
|
||||
TRANSFORM_CORE_AIO_TAG=2.2.1
|
||||
SHARED_FILE_STORE_TAG=0.7.0
|
||||
ACTIVE_MQ_TAG=5.15.8
|
||||
DIGITAL_WORKSPACE_TAG=1.5.0
|
||||
ACS_NGINX_TAG=3.0.1
|
||||
ACS_COMMUNITY_NGINX_TAG=1.0.0
|
||||
SEARCH_TAG=latest
|
||||
ZEPPELIN_TAG=latest
|
||||
ACA_TAG=master-latest
|
8322
e2e-test/generator-alfresco-docker-compose/package-lock.json
generated
8322
e2e-test/generator-alfresco-docker-compose/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -21,10 +21,9 @@
|
||||
"npm": ">= 4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": "^2.1.0",
|
||||
"yeoman-generator": "^2.0.1",
|
||||
"yo": "^3.1.1",
|
||||
"yosay": "^2.0.1"
|
||||
"chalk": "^2.4.2",
|
||||
"yeoman-generator": "^4.12.0",
|
||||
"yosay": "^2.0.2"
|
||||
},
|
||||
"jest": {
|
||||
"testEnvironment": "node"
|
||||
|
@@ -30,6 +30,7 @@ JAVA_OPTS = ('-Ddb.driver=org.postgresql.Driver -Ddb.username=alfresco -Ddb.pass
|
||||
'-Dsolr.http.connection.timeout=3000 ')
|
||||
MTLS_OPTS = ('-Dsolr.port.ssl=8983 -Dsolr.secureComms=https ')
|
||||
HTTP_OPTS = ('-Dsolr.secureComms=none')
|
||||
SECRET_OPTS = ('-Dsolr.secureComms=secret -Dsolr.sharedSecret=secret')
|
||||
JAVA_TOOL_OPTIONS = ('-Dencryption.keystore.type=JCEKS '
|
||||
'-Dencryption.cipherAlgorithm=DESede/CBC/PKCS5Padding '
|
||||
'-Dencryption.keyAlgorithm=DESede '
|
||||
@@ -48,7 +49,7 @@ MTLS_JAVA_TOOL_OPTIONS = ('-Dencryption.keystore.type=pkcs12 -Dencryption.cipher
|
||||
'-Dssl-truststore.alfresco-ca.password=kT9X6oe68t '
|
||||
'-Dssl-truststore.ssl-repo-client.password=kT9X6oe68t')
|
||||
|
||||
def getJavaOpts(includeAMQ, includeTransform, includeShare, solrHost, solrBaseUrl, sharding, mtls):
|
||||
def getJavaOpts(includeAMQ, includeTransform, includeShare, solrHost, solrBaseUrl, sharding, communication):
|
||||
|
||||
solrHost = '-Dsolr.host=' + solrHost
|
||||
shardingOpts = (SHARDING_OPTS if sharding != None else '')
|
||||
@@ -56,13 +57,18 @@ def getJavaOpts(includeAMQ, includeTransform, includeShare, solrHost, solrBaseUr
|
||||
transformOpts = (TRANSFORM_OPTS if includeTransform else '')
|
||||
solrBaseUrlOpts = '-Dsolr.baseUrl=' + solrBaseUrl
|
||||
shareTransformOpts = (SHARE_TRANSFORM_OPTS if includeShare and includeTransform else '')
|
||||
mtlsOpts = (MTLS_OPTS if mtls else HTTP_OPTS)
|
||||
if communication == 'mtls':
|
||||
commOpts = MTLS_OPTS
|
||||
elif communication == 'none':
|
||||
commOpts = HTTP_OPTS
|
||||
else :
|
||||
commOpts = SECRET_OPTS
|
||||
|
||||
return ' '.join([JAVA_OPTS, amqOpts, transformOpts, shareTransformOpts, solrHost, solrBaseUrlOpts, shardingOpts, mtlsOpts])
|
||||
return ' '.join([JAVA_OPTS, amqOpts, transformOpts, shareTransformOpts, solrHost, solrBaseUrlOpts, shardingOpts, commOpts])
|
||||
|
||||
def getJavaToolOptions(mtls):
|
||||
def getJavaToolOptions(communication):
|
||||
|
||||
mtlsJavaToolOptions = (MTLS_JAVA_TOOL_OPTIONS if mtls else '')
|
||||
mtlsJavaToolOptions = (MTLS_JAVA_TOOL_OPTIONS if communication == 'mtls' else '')
|
||||
|
||||
return ' '.join([JAVA_TOOL_OPTIONS, mtlsJavaToolOptions])
|
||||
|
||||
@@ -108,19 +114,21 @@ def getSolrcoreConfig(sharding, shardId, shardCount, shardRange):
|
||||
print("SolrConfig for Shard: ", shardId, " : ", solrcoreConfig)
|
||||
return solrcoreConfig
|
||||
|
||||
def getSolrcoreReplacements(sharding, mtls):
|
||||
def getSolrcoreReplacements(sharding, communication):
|
||||
"""Returns a dict of replacements to make in the solrcore.properties file."""
|
||||
solrcoreReplacements = {}
|
||||
if sharding != None:
|
||||
solrcoreReplacements['shard.method=DB_ID'] = 'shard.method={}'.format(sharding)
|
||||
if mtls:
|
||||
if communication == 'mtls':
|
||||
solrcoreReplacements['alfresco.secureComms=none'] = 'alfresco.secureComms=https'
|
||||
solrcoreReplacements['alfresco.encryption.ssl.keystore.location=.*'] = 'alfresco.encryption.ssl.keystore.location=\\\\\\/opt\\\\\\/alfresco-search-services\\\\\\/keystore\\\\\\/ssl-repo-client.keystore'
|
||||
solrcoreReplacements['alfresco.encryption.ssl.keystore.type=.*'] = 'alfresco.encryption.ssl.keystore.type=JCEKS'
|
||||
solrcoreReplacements['alfresco.encryption.ssl.truststore.location=.*'] = 'alfresco.encryption.ssl.truststore.location=\\\\\\/opt\\\\\\/alfresco-search-services\\\\\\/keystore\\\\\\/ssl-repo-client.truststore'
|
||||
solrcoreReplacements['alfresco.encryption.ssl.truststore.type=.*'] = 'alfresco.encryption.ssl.truststore.type=JCEKS'
|
||||
else:
|
||||
elif communication == 'none':
|
||||
solrcoreReplacements['alfresco.secureComms=https'] = 'alfresco.secureComms=none'
|
||||
else :
|
||||
solrcoreReplacements['alfresco.secureComms=https'] = 'alfresco.secureComms=secret'
|
||||
return solrcoreReplacements
|
||||
|
||||
def addAlfrescoMtlsConfig(alfrescoArgsNode):
|
||||
@@ -168,11 +176,15 @@ def addSolrVolumes(solrNode):
|
||||
"""Add route to keystores folder"""
|
||||
solrNode['volumes'] = ['./keystores/solr:/opt/alfresco-search-services/keystore']
|
||||
|
||||
def makeSearchNode(outputDirectory, nodeName, externalPort, params, mtls, extraEnvironmentVars={}, solrcoreConfig=[], solrcoreReplacements={}):
|
||||
def addSharedSecretSolrOpts(solrEnvNode):
|
||||
"""Add a list of values to add in Docker Compose SOLR_OPTS property for Shared Secret communication."""
|
||||
solrEnvNode['SOLR_OPTS'] = '-Dalfresco.secureComms.secret=secret'
|
||||
|
||||
def makeSearchNode(outputDirectory, nodeName, externalPort, params, communication, extraEnvironmentVars={}, solrcoreConfig=[], solrcoreReplacements={}):
|
||||
# Create a dictionary for the template replacement.
|
||||
allParams = dict(params)
|
||||
allParams['SOLR_HOST'] = nodeName
|
||||
allParams['ALFRESCO_PORT'] = 8443 if mtls else 8080
|
||||
allParams['ALFRESCO_PORT'] = 8443 if communication == 'mtls' else 8080
|
||||
allParams['EXTERNAL_PORT'] = externalPort
|
||||
# Properties to add to solrcore.properties.
|
||||
allParams['SOLRCORE_PROPERTIES'] = '\\n'.join(solrcoreConfig)
|
||||
@@ -180,7 +192,13 @@ def makeSearchNode(outputDirectory, nodeName, externalPort, params, mtls, extraE
|
||||
allParams['SOLRCORE_REPLACEMENTS'] = ' '.join(map(lambda pair: '"{}/{}"'.format(*pair), solrcoreReplacements.items()))
|
||||
|
||||
# mTLS settings
|
||||
allParams['ALFRESCO_SECURE_COMMS'] = ('https' if mtls else 'none')
|
||||
if communication == 'mtls':
|
||||
allParams['ALFRESCO_SECURE_COMMS'] = 'https'
|
||||
elif communication == 'none':
|
||||
allParams['ALFRESCO_SECURE_COMMS'] = 'none'
|
||||
else :
|
||||
allParams['ALFRESCO_SECURE_COMMS'] = 'secret'
|
||||
|
||||
allParams['TRUSTSTORE_TYPE'] = 'JCEKS'
|
||||
allParams['KEYSTORE_TYPE'] = 'JCEKS'
|
||||
|
||||
@@ -203,12 +221,16 @@ def makeSearchNode(outputDirectory, nodeName, externalPort, params, mtls, extraE
|
||||
searchNodeYaml['environment'].update(extraEnvironmentVars)
|
||||
|
||||
# Add mTLS configuration if required
|
||||
if mtls:
|
||||
if communication == 'mtls':
|
||||
addSolrMtlsConfig(searchNodeYaml['environment'])
|
||||
addSolrOpts(searchNodeYaml['environment'])
|
||||
addSolrJavaToolOptions(searchNodeYaml['environment'])
|
||||
addSolrVolumes(searchNodeYaml)
|
||||
|
||||
# Add shared secret configuration if required
|
||||
if communication == 'secret':
|
||||
addSharedSecretSolrOpts(searchNodeYaml['environment'])
|
||||
|
||||
return searchNodeYaml
|
||||
|
||||
if __name__ == '__main__':
|
||||
@@ -231,7 +253,8 @@ if __name__ == '__main__':
|
||||
parser.add_argument('-sl', '--searchLogLevel', default='WARN', help='The log level for search (default WARN)',
|
||||
choices=['TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR'])
|
||||
parser.add_argument('-o', '--output', default='.', help='The path of the directory to output to')
|
||||
parser.add_argument('-mtls', '--mtls', action='store_true', help='Use mTLS between SOLR and Alfresco Repository')
|
||||
parser.add_argument('-comm', '--communication', default='none', help='Use none, mtls or secret communication between SOLR and Alfresco Repository',
|
||||
choices=['none', 'mtls', 'secret'])
|
||||
args = parser.parse_args()
|
||||
|
||||
# If sharding is selected then the default number of shards is two.
|
||||
@@ -280,20 +303,20 @@ if __name__ == '__main__':
|
||||
if shardId == 0 and replicationType == 'standalone':
|
||||
serviceName = 'search'
|
||||
externalPort = 8083 + 100 * shardId + (1 if replicationType == 'slave' else 0)
|
||||
dcYaml['services'][serviceName] = makeSearchNode(args.output, serviceName, externalPort, params, args.mtls,
|
||||
dcYaml['services'][serviceName] = makeSearchNode(args.output, serviceName, externalPort, params, args.communication,
|
||||
extraEnvironmentVars=getExtraEnvironmentVars(serviceName, replicationType),
|
||||
solrcoreConfig=getSolrcoreConfig(args.sharding, shardId, args.shardCount, args.shardRange),
|
||||
solrcoreReplacements=getSolrcoreReplacements(args.sharding, args.mtls))
|
||||
solrcoreReplacements=getSolrcoreReplacements(args.sharding, args.communication))
|
||||
|
||||
# Point Alfresco at whichever Solr node came last in the list.
|
||||
solrHost = serviceName
|
||||
solrBaseUrl = '/solr-slave' if args.masterslave else '/solr'
|
||||
|
||||
javaOpts = getJavaOpts(not args.excludeAMQ, args.transformer == AIO_TRANSFORMERS, args.share != None, solrHost, solrBaseUrl, args.sharding, args.mtls)
|
||||
javaOpts = getJavaOpts(not args.excludeAMQ, args.transformer == AIO_TRANSFORMERS, args.share != None, solrHost, solrBaseUrl, args.sharding, args.communication)
|
||||
dcYaml['services']['alfresco']['environment']['JAVA_OPTS'] = javaOpts
|
||||
javaToolOpts = getJavaToolOptions(args.mtls)
|
||||
javaToolOpts = getJavaToolOptions(args.communication)
|
||||
dcYaml['services']['alfresco']['environment']['JAVA_TOOL_OPTIONS'] = javaToolOpts
|
||||
if args.mtls:
|
||||
if args.communication == 'mtls':
|
||||
addAlfrescoMtlsConfig(dcYaml['services']['alfresco']['build']['args'])
|
||||
addAlfrescoVolumes(dcYaml['services']['alfresco'])
|
||||
|
||||
@@ -321,5 +344,5 @@ if __name__ == '__main__':
|
||||
dockerfileTemplate = f.write(dockerfileString)
|
||||
|
||||
# Copy the keystores (when using mTLS)
|
||||
if args.mtls:
|
||||
if args.communication == 'mtls':
|
||||
copy_tree(scriptDir + '/keystores', args.output + '/keystores')
|
||||
|
@@ -45,6 +45,7 @@ import org.alfresco.solr.SolrInformationServer;
|
||||
import org.alfresco.solr.SolrKeyResourceLoader;
|
||||
import org.alfresco.solr.client.SOLRAPIClient;
|
||||
import org.alfresco.solr.client.SOLRAPIClientFactory;
|
||||
import org.alfresco.solr.security.SecretSharedPropertyCollector;
|
||||
import org.alfresco.solr.tracker.AclTracker;
|
||||
import org.alfresco.solr.tracker.CascadeTracker;
|
||||
import org.alfresco.solr.tracker.CommitTracker;
|
||||
@@ -113,6 +114,9 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener
|
||||
|
||||
TrackerRegistry trackerRegistry = admin.getTrackerRegistry();
|
||||
Properties coreProperties = new CoreDescriptorDecorator(core.getCoreDescriptor()).getProperties();
|
||||
|
||||
// Add secret shared properties if required, as they are passed as Java Environment Variables
|
||||
coreProperties = SecretSharedPropertyCollector.completeCoreProperties(coreProperties);
|
||||
|
||||
SolrResourceLoader loader = core.getLatestSchema().getResourceLoader();
|
||||
SolrKeyResourceLoader keyResourceLoader = new SolrKeyResourceLoader(loader);
|
||||
|
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Search Services
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2020 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.solr.security;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.solr.security.AuthenticationPlugin;
|
||||
|
||||
/**
|
||||
* SOLR Authentication Plugin based in shared secret token via request header.
|
||||
*
|
||||
* This Web Filter is loaded from SOLR_HOME/security.json file, so it will be executed
|
||||
* for every request to SOLR. Authentication logic is only applied when Alfresco Communication
|
||||
* is using "secret" method but it doesn't apply to "none" and "https" methods.
|
||||
*
|
||||
*/
|
||||
public class SecretSharedAuthPlugin extends AuthenticationPlugin
|
||||
{
|
||||
|
||||
/**
|
||||
* Verify that request header includes "secret" word when using "secret" communication method.
|
||||
* "alfresco.secureComms.secret" value is expected as Java environment variable.
|
||||
*/
|
||||
@Override
|
||||
public boolean doAuthenticate(ServletRequest request, ServletResponse response, FilterChain chain) throws Exception
|
||||
{
|
||||
|
||||
if (SecretSharedPropertyCollector.isCommsSecretShared())
|
||||
{
|
||||
|
||||
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||
|
||||
if (Objects.equals(httpRequest.getHeader(SecretSharedPropertyCollector.getSecretHeader()),
|
||||
SecretSharedPropertyCollector.getSecret()))
|
||||
{
|
||||
chain.doFilter(request, response);
|
||||
return true;
|
||||
}
|
||||
|
||||
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||
httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN,
|
||||
"Authentication failure: \"" + SecretSharedPropertyCollector.SECRET_SHARED_METHOD_KEY
|
||||
+ "\" method has been selected, use the right request header with the secret word");
|
||||
return false;
|
||||
}
|
||||
|
||||
chain.doFilter(request, response);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Map<String, Object> parameters)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Search Services
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2020 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.solr.security;
|
||||
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.alfresco.httpclient.HttpClientFactory;
|
||||
import org.alfresco.solr.AlfrescoSolrDataModel;
|
||||
import org.alfresco.solr.config.ConfigUtil;
|
||||
import org.apache.solr.core.SolrResourceLoader;
|
||||
|
||||
/**
|
||||
* Provides property values for Alfresco Communication using "secret" method:
|
||||
*
|
||||
* - "alfresco.secureComms" is the commsMethod (none, https or secret)
|
||||
* - "alfresco.secureComms.secret" is the word used as shared secret for "secret" method
|
||||
* - "alfresco.secureComms.secret.header" is the request header name used for "secret" method
|
||||
*
|
||||
*/
|
||||
public class SecretSharedPropertyCollector
|
||||
{
|
||||
|
||||
public final static String SECRET_SHARED_METHOD_KEY = "secret";
|
||||
|
||||
// Property names for "secret" communication method
|
||||
private static String SECURE_COMMS_PROPERTY = "alfresco.secureComms";
|
||||
private static String SHARED_SECRET = "alfresco.secureComms.secret";
|
||||
private static String SHARED_SECRET_HEADER = "alfresco.secureComms.secret.header";
|
||||
|
||||
// Save communication method as static value in order to improve performance
|
||||
private static String commsMethod;
|
||||
|
||||
/**
|
||||
* Check if communications method is "secret"
|
||||
* @return true when communications method is "secret"
|
||||
*/
|
||||
public static boolean isCommsSecretShared()
|
||||
{
|
||||
return Objects.equals(SecretSharedPropertyCollector.getCommsMethod(),
|
||||
SecretSharedPropertyCollector.SECRET_SHARED_METHOD_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get communication method from environment variables, shared properties or core properties.
|
||||
* @return Communication method: none, https, secret
|
||||
*/
|
||||
private static String getCommsMethod()
|
||||
{
|
||||
|
||||
if (commsMethod == null)
|
||||
{
|
||||
|
||||
// Environment variable
|
||||
commsMethod = ConfigUtil.locateProperty(SECURE_COMMS_PROPERTY, null);
|
||||
|
||||
if (commsMethod == null)
|
||||
{
|
||||
// Shared configuration (shared.properties file)
|
||||
commsMethod = AlfrescoSolrDataModel.getCommonConfig().getProperty(SECURE_COMMS_PROPERTY);
|
||||
|
||||
if (commsMethod == null)
|
||||
{
|
||||
// Get configuration from deployed SOLR Cores
|
||||
Set<String> secureCommsSet = getCommsFromCores();
|
||||
if (secureCommsSet.size() > 1 && secureCommsSet.contains(SECRET_SHARED_METHOD_KEY))
|
||||
{
|
||||
throw new RuntimeException(
|
||||
"No valid secure comms values: all the cores must be using \"secret\" communication method but found: "
|
||||
+ secureCommsSet);
|
||||
}
|
||||
commsMethod = secureCommsSet.stream().findFirst().get();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return commsMethod;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Read different values of "alfresco.secureComms" property from every "solrcore.properties" files.
|
||||
* @return List of different communication methods declared in SOLR Cores.
|
||||
*/
|
||||
private static Set<String> getCommsFromCores()
|
||||
{
|
||||
|
||||
Set<String> secureCommsSet = new HashSet<>();
|
||||
|
||||
try (Stream<Path> walk = Files.walk(Paths.get(SolrResourceLoader.locateSolrHome().toString())))
|
||||
{
|
||||
|
||||
List<String> coreFiles = walk.map(x -> x.toString())
|
||||
.filter(f -> f.contains("solrcore.properties") && !f.contains("templates"))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
coreFiles.forEach(coreFile -> {
|
||||
|
||||
Properties props = new Properties();
|
||||
try
|
||||
{
|
||||
props.load(new FileReader(coreFile));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
String prop = props.getProperty(SECURE_COMMS_PROPERTY);
|
||||
if (prop != null)
|
||||
{
|
||||
secureCommsSet.add(prop);
|
||||
}
|
||||
else
|
||||
{
|
||||
secureCommsSet.add("none");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return secureCommsSet;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Read "secret" word from Java environment variable "alfresco.secureComms.secret"
|
||||
*
|
||||
* It can be set from command line invocation using default "-D" parameter:
|
||||
*
|
||||
* solr start -a "-Dcreate.alfresco.defaults=alfresco -Dalfresco.secureComms.secret=secret"
|
||||
*
|
||||
* @return value for the "secret" word
|
||||
*/
|
||||
public static String getSecret()
|
||||
{
|
||||
String secret = ConfigUtil.locateProperty(SHARED_SECRET, null);
|
||||
|
||||
if (secret == null || secret.length() == 0)
|
||||
{
|
||||
throw new RuntimeException("Missing value for " + SHARED_SECRET + " configuration property");
|
||||
}
|
||||
|
||||
return secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read secret request header name from Java environment variable "alfresco.secureComms.secret.header".
|
||||
* If it's not specified, used default value "X-Alfresco-Search-Secret"
|
||||
*
|
||||
* @return value for the secret request header
|
||||
*/
|
||||
public static String getSecretHeader()
|
||||
{
|
||||
String secretHeader = ConfigUtil.locateProperty(SHARED_SECRET_HEADER, null);
|
||||
if (secretHeader != null)
|
||||
{
|
||||
return secretHeader;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HttpClientFactory.DEFAULT_SHAREDSECRET_HEADER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add secret shared properties to original core properties read from "solrcore.properties"
|
||||
* @param properties Read properties from "solrcore.properties"
|
||||
* @return when "secret" communication method is configured additional properties are set in original parameter
|
||||
*/
|
||||
public static Properties completeCoreProperties(Properties properties)
|
||||
{
|
||||
if (isCommsSecretShared())
|
||||
{
|
||||
properties.setProperty(SECURE_COMMS_PROPERTY, getCommsMethod());
|
||||
properties.setProperty(SHARED_SECRET, getSecret());
|
||||
properties.setProperty(SHARED_SECRET_HEADER, getSecretHeader());
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"authentication" : {
|
||||
"class": "org.alfresco.solr.security.SecretSharedAuthPlugin"
|
||||
}
|
||||
}
|
@@ -11,8 +11,8 @@
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<dependency.alfresco-data-model.version>8.319</dependency.alfresco-data-model.version>
|
||||
<dependency.jackson.version>2.11.3</dependency.jackson.version>
|
||||
<dependency.alfresco-data-model.version>11.8</dependency.alfresco-data-model.version>
|
||||
<dependency.jackson.version>2.12.2</dependency.jackson.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@@ -50,13 +50,13 @@
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13</version>
|
||||
<version>4.13.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>3.4.6</version>
|
||||
<version>3.8.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@@ -52,8 +52,13 @@ public class SOLRAPIClientFactory
|
||||
*/
|
||||
private static Map<String, SOLRAPIClient> clientsPerAlfresco = new HashMap<>();
|
||||
|
||||
// encryption related parameters
|
||||
private String secureCommsType; // "none", "https"
|
||||
// http communication related parameters
|
||||
private String secureCommsType; // "none", "https", "secret"
|
||||
|
||||
// http
|
||||
private String alfrescoHost;
|
||||
private int alfrescoPort;
|
||||
private String baseUrl;
|
||||
|
||||
// ssl
|
||||
private String sslKeyStoreType;
|
||||
@@ -64,19 +69,21 @@ public class SOLRAPIClientFactory
|
||||
private String sslTrustStoreProvider;
|
||||
private String sslTrustStoreLocation;
|
||||
private String sslTrustStorePasswordFileLocation;
|
||||
private String alfrescoHost;
|
||||
private int alfrescoPort;
|
||||
private int alfrescoPortSSL;
|
||||
private String baseUrl;
|
||||
|
||||
// http client
|
||||
// secret shared
|
||||
private String secret;
|
||||
private String secretHeader;
|
||||
|
||||
// http client settings
|
||||
private int maxTotalConnections = 40;
|
||||
private int maxHostConnections = 40;
|
||||
private int socketTimeout = 120000;
|
||||
|
||||
|
||||
public static void close() {
|
||||
for(SOLRAPIClient client : clientsPerAlfresco.values()) {
|
||||
public static void close()
|
||||
{
|
||||
for (SOLRAPIClient client : clientsPerAlfresco.values())
|
||||
{
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
@@ -131,12 +138,13 @@ public class SOLRAPIClientFactory
|
||||
* @param namespaceDAO allows retrieving and creating Namespace definitions
|
||||
* @return an instance of SOLRAPIClient
|
||||
*/
|
||||
public SOLRAPIClient getSOLRAPIClient(Properties props, KeyResourceLoader keyResourceLoader, DictionaryService dictionaryService, NamespaceDAO namespaceDAO)
|
||||
public SOLRAPIClient getSOLRAPIClient(Properties props, KeyResourceLoader keyResourceLoader,
|
||||
DictionaryService dictionaryService, NamespaceDAO namespaceDAO)
|
||||
{
|
||||
|
||||
if (Boolean.parseBoolean(System.getProperty("alfresco.test", "false")))
|
||||
{
|
||||
return new SOLRAPIQueueClient(namespaceDAO);
|
||||
{
|
||||
return new SOLRAPIQueueClient(namespaceDAO);
|
||||
}
|
||||
|
||||
alfrescoHost = props.getProperty("alfresco.host", "localhost");
|
||||
@@ -150,20 +158,25 @@ public class SOLRAPIClientFactory
|
||||
baseUrl = props.getProperty("alfresco.baseUrl", "/alfresco");
|
||||
// Load SSL settings only when using HTTPs protocol
|
||||
secureCommsType = props.getProperty("alfresco.secureComms", "none");
|
||||
if (secureCommsType.equals("https"))
|
||||
if (SecureCommsType.getType(secureCommsType) == SecureCommsType.HTTPS)
|
||||
{
|
||||
sslKeyStoreType = getProperty(props, "alfresco.encryption.ssl.keystore.type", "JCEKS");
|
||||
sslKeyStoreProvider = getProperty(props, "alfresco.encryption.ssl.keystore.provider", "");
|
||||
sslKeyStoreLocation = getProperty(props, "alfresco.encryption.ssl.keystore.location",
|
||||
"ssl.repo.client.keystore");
|
||||
"ssl.repo.client.keystore");
|
||||
sslKeyStorePasswordFileLocation = getProperty(props,
|
||||
"alfresco.encryption.ssl.keystore.passwordFileLocation", "");
|
||||
"alfresco.encryption.ssl.keystore.passwordFileLocation", "");
|
||||
sslTrustStoreType = getProperty(props, "alfresco.encryption.ssl.truststore.type", "JCEKS");
|
||||
sslTrustStoreProvider = getProperty(props, "alfresco.encryption.ssl.truststore.provider", "");
|
||||
sslTrustStoreLocation = getProperty(props, "alfresco.encryption.ssl.truststore.location",
|
||||
"ssl.repo.client.truststore");
|
||||
"ssl.repo.client.truststore");
|
||||
sslTrustStorePasswordFileLocation = getProperty(props,
|
||||
"alfresco.encryption.ssl.truststore.passwordFileLocation", "");
|
||||
"alfresco.encryption.ssl.truststore.passwordFileLocation", "");
|
||||
}
|
||||
if (SecureCommsType.getType(secureCommsType) == SecureCommsType.SECRET)
|
||||
{
|
||||
secret = getProperty(props, "alfresco.secureComms.secret", "");
|
||||
secretHeader = getProperty(props, "alfresco.secureComms.secret.header", "");
|
||||
}
|
||||
maxTotalConnections = Integer.parseInt(props.getProperty("alfresco.maxTotalConnections", "40"));
|
||||
maxHostConnections = Integer.parseInt(props.getProperty("alfresco.maxHostConnections", "40"));
|
||||
@@ -175,69 +188,76 @@ public class SOLRAPIClientFactory
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
|
||||
protected AlfrescoHttpClient getRepoClient(KeyResourceLoader keyResourceLoader)
|
||||
{
|
||||
HttpClientFactory httpClientFactory = null;
|
||||
|
||||
if (secureCommsType.equals("https"))
|
||||
if (SecureCommsType.getType(secureCommsType) == SecureCommsType.HTTPS)
|
||||
{
|
||||
KeyStoreParameters keyStoreParameters = new KeyStoreParameters("ssl-keystore", "SSL Key Store",
|
||||
sslKeyStoreType, sslKeyStoreProvider, sslKeyStorePasswordFileLocation, sslKeyStoreLocation);
|
||||
sslKeyStoreType, sslKeyStoreProvider, sslKeyStorePasswordFileLocation, sslKeyStoreLocation);
|
||||
KeyStoreParameters trustStoreParameters = new KeyStoreParameters("ssl-truststore", "SSL Trust Store",
|
||||
sslTrustStoreType, sslTrustStoreProvider, sslTrustStorePasswordFileLocation, sslTrustStoreLocation);
|
||||
sslTrustStoreType, sslTrustStoreProvider, sslTrustStorePasswordFileLocation,
|
||||
sslTrustStoreLocation);
|
||||
SSLEncryptionParameters sslEncryptionParameters = new SSLEncryptionParameters(keyStoreParameters,
|
||||
trustStoreParameters);
|
||||
trustStoreParameters);
|
||||
httpClientFactory = new HttpClientFactory(SecureCommsType.getType(secureCommsType), sslEncryptionParameters,
|
||||
keyResourceLoader, null, null, alfrescoHost, alfrescoPort, alfrescoPortSSL, maxTotalConnections,
|
||||
maxHostConnections, socketTimeout);
|
||||
keyResourceLoader, null, null, null, null, alfrescoHost, alfrescoPort, alfrescoPortSSL,
|
||||
maxTotalConnections, maxHostConnections, socketTimeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
httpClientFactory = new PlainHttpClientFactory(alfrescoHost, alfrescoPort, maxTotalConnections,
|
||||
maxHostConnections, socketTimeout);
|
||||
httpClientFactory = new PlainHttpClientFactory(secureCommsType, alfrescoHost, alfrescoPort,
|
||||
maxTotalConnections, maxHostConnections, socketTimeout);
|
||||
if (SecureCommsType.getType(secureCommsType) == SecureCommsType.SECRET)
|
||||
{
|
||||
httpClientFactory.setSharedSecret(secret);
|
||||
httpClientFactory.setSharedSecretHeader(secretHeader);
|
||||
}
|
||||
}
|
||||
|
||||
AlfrescoHttpClient repoClient = httpClientFactory.getRepoClient(alfrescoHost, alfrescoPortSSL);
|
||||
|
||||
repoClient.setBaseUrl(baseUrl);
|
||||
return repoClient;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return property value from system (passed as -D argument).
|
||||
* If the system property does not exists, return local value from solrcore.properties
|
||||
* Return property value from system (passed as -D argument).
|
||||
* If the system property does not exists, return local value from solrcore.properties
|
||||
* If the local property does not exists, return default value
|
||||
*
|
||||
* @param props Local properties file (solrcore.properties)
|
||||
* @param key The property key
|
||||
* @return The value
|
||||
*/
|
||||
private String getProperty(Properties props, String key, String defaultValue)
|
||||
private String getProperty(Properties props, String key, String defaultValue)
|
||||
{
|
||||
String value = System.getProperties().getProperty(key);
|
||||
if (value == null)
|
||||
{
|
||||
value = props.getProperty(key);
|
||||
}
|
||||
if (value == null)
|
||||
{
|
||||
value = defaultValue;
|
||||
}
|
||||
return value;
|
||||
String value = System.getProperties().getProperty(key);
|
||||
if (value == null)
|
||||
{
|
||||
value = props.getProperty(key);
|
||||
}
|
||||
if (value == null)
|
||||
{
|
||||
value = defaultValue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Local class to avoid loading sslEntryptionParameters for plain http connections.
|
||||
* Local class to avoid loading sslEntryptionParameters for plain http connections.
|
||||
*
|
||||
* @author aborroy
|
||||
*
|
||||
*/
|
||||
class PlainHttpClientFactory extends HttpClientFactory
|
||||
{
|
||||
public PlainHttpClientFactory(String host, int port, int maxTotalConnections, int maxHostConnections, int socketTimeout)
|
||||
public PlainHttpClientFactory(String secureCommsType, String host, int port, int maxTotalConnections,
|
||||
int maxHostConnections, int socketTimeout)
|
||||
{
|
||||
setSecureCommsType("none");
|
||||
setSecureCommsType(secureCommsType);
|
||||
setHost(host);
|
||||
setPort(port);
|
||||
setMaxTotalConnections(maxTotalConnections);
|
||||
|
@@ -28,7 +28,7 @@ xpp3-1.1.4c.jar http://www.extreme.indiana.edu/dist/java-repository/xpp3/license
|
||||
|
||||
|
||||
=== JSON ===
|
||||
json-20200518.jar https://github.com/stleary/JSON-java
|
||||
json-20210307.jar https://github.com/stleary/JSON-java
|
||||
|
||||
|
||||
=== Apache 2.0 ===
|
||||
@@ -36,7 +36,7 @@ xml-resolver-1.2.jar https://github.com/FasterXML/jackson
|
||||
neethi-3.1.1.jar http://ws.apache.org/commons/neethi/
|
||||
commons-dbcp-1.4.jar http://jakarta.apache.org/commons/
|
||||
commons-logging-1.1.3.jar http://jakarta.apache.org/commons/
|
||||
commons-lang3-3.11.jar http://jakarta.apache.org/commons/
|
||||
commons-lang3-3.12.0.jar http://jakarta.apache.org/commons/
|
||||
commons-pool-1.5.4.jar http://jakarta.apache.org/commons/
|
||||
chemistry-opencmis-commons-impl-1.1.0.jar http://chemistry.apache.org/
|
||||
chemistry-opencmis-commons-api-1.1.0.jar http://chemistry.apache.org/
|
||||
@@ -55,19 +55,19 @@ cxf-rt-wsdl-3.2.14.jar https://cxf.apache.org/
|
||||
chemistry-opencmis-server-support-1.0.0.jar http://chemistry.apache.org/
|
||||
chemistry-opencmis-server-bindings-1.0.0.jar http://chemistry.apache.org/
|
||||
quartz-2.3.2.jar http://quartz-scheduler.org/
|
||||
jackson-core-2.11.3.jar https://github.com/FasterXML/jackson
|
||||
jackson-annotations-2.11.3.jar https://github.com/FasterXML/jackson
|
||||
jackson-databind-2.11.3.jar https://github.com/FasterXML/jackson
|
||||
jackson-core-2.12.2.jar https://github.com/FasterXML/jackson
|
||||
jackson-annotations-2.12.2.jar https://github.com/FasterXML/jackson
|
||||
jackson-databind-2.12.2.jar https://github.com/FasterXML/jackson
|
||||
commons-httpclient-3.1-HTTPCLIENT-1265.jar http://jakarta.apache.org/commons/
|
||||
spring-aop-5.2.9.RELEASE.jar http://projects.spring.io/spring-framework/
|
||||
spring-beans-5.2.9.RELEASE.jar http://projects.spring.io/spring-framework/
|
||||
spring-context-5.2.9.RELEASE.jar http://projects.spring.io/spring-framework/
|
||||
spring-core-5.2.9.RELEASE.jar http://projects.spring.io/spring-framework/
|
||||
spring-expression-5.2.9.RELEASE.jar http://projects.spring.io/spring-framework/
|
||||
spring-jdbc-5.2.9.RELEASE.jar http://projects.spring.io/spring-framework/
|
||||
spring-orm-5.2.9.RELEASE.jar http://projects.spring.io/spring-framework/
|
||||
spring-tx-5.2.9.RELEASE.jar http://projects.spring.io/spring-framework/
|
||||
xercesImpl-2.12.0-alfresco-patched-20191004.jar http://xerces.apache.org/xerces2-j
|
||||
spring-aop-5.3.3.jar http://projects.spring.io/spring-framework/
|
||||
spring-beans-5.3.3.jar http://projects.spring.io/spring-framework/
|
||||
spring-context-5.3.3.jar http://projects.spring.io/spring-framework/
|
||||
spring-core-5.3.3.jar http://projects.spring.io/spring-framework/
|
||||
spring-expression-5.3.3.jar http://projects.spring.io/spring-framework/
|
||||
spring-jdbc-5.3.3.jar http://projects.spring.io/spring-framework/
|
||||
spring-orm-5.3.3.jar http://projects.spring.io/spring-framework/
|
||||
spring-tx-5.3.3.jar http://projects.spring.io/spring-framework/
|
||||
xercesImpl-2.12.1.jar http://xerces.apache.org/xerces2-j
|
||||
guessencoding-1.4.jar http://docs.codehaus.org/display/GUESSENC/
|
||||
jug-2.0.0-asl.jar http://jug.safehaus.org/
|
||||
acegi-security-0.8.2_patched.jar http://sourceforge.net/projects/acegisecurity/
|
||||
@@ -89,16 +89,18 @@ aggdesigner-algorithm-6.0.jar https://github.com/julianhyde/aggdesigner
|
||||
|
||||
|
||||
=== CDDL 1.1 ===
|
||||
jaxb-core-2.3.0.1.jar http://jaxb.java.net/
|
||||
jaxb-xjc-2.3.3.jar http://jaxb.java.net/
|
||||
jaxb-impl-2.3.3.jar http://jaxb.java.net/
|
||||
jaxb-core-3.0.0.jar http://jaxb.java.net/
|
||||
jaxb-runtime-2.3.3.jar http://jaxb.java.net/
|
||||
jaxb-xjc-3.0.0.jar http://jaxb.java.net/
|
||||
|
||||
|
||||
=== Eclipse Distribution License 1.0 (BSD) ===
|
||||
jakarta.activation-1.2.2.jar https://eclipse-ee4j.github.io/jaf
|
||||
jakarta.jws-api-1.1.1.jar https://projects.eclipse.org/projects/ee4j.websocket/releases/1.1.1
|
||||
jakarta.xml.bind-api-2.3.3.jar https://projects.eclipse.org/projects/ee4j.jaxb
|
||||
|
||||
jakarta.activation-2.0.0.jar https://eclipse-ee4j.github.io/jaf
|
||||
jakarta.activation-api-1.2.2.jar https://eclipse-ee4j.github.io/jaf
|
||||
jakarta.jws-api-2.1.0.jar https://projects.eclipse.org/projects/ee4j.websocket/releases/1.1.1
|
||||
jakarta.xml.bind-api-3.0.0.jar https://projects.eclipse.org/projects/ee4j.jaxb
|
||||
istack-commons-runtime-3.0.11.jar https://projects.eclipse.org/projects/ee4j.jaxb-impl
|
||||
txw2-2.3.3.jar https://eclipse-ee4j.github.io/jaxb-ri
|
||||
|
||||
=== Eclipse Public License 2.0 ===
|
||||
jakarta.annotation-api-1.3.5.jar https://projects.eclipse.org/projects/ee4j.ca
|
||||
|
Reference in New Issue
Block a user