diff --git a/.gitignore b/.gitignore index 4f728fb..10bd581 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .DS_Store configuration-profiles/dev/ -resources/data/ \ No newline at end of file +resources/data/ +compose-profiles/test-network-* +configuration-profiles/test-network-* diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..4844c3b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,30 @@ +sudo: required +language: minimal +services: + - docker + - postgresql + +notifications: + email: false + +env: + #MEDCO_DB_NUMBER is the number of databases used in the profile that will be tested + - MEDCO_DB_NUMBER=9 MEDCO_DB_HOST=localhost MEDCO_DB_PORT=5432 MEDCO_DB_USER=postgres MEDCO_DB_PASSWORD=postgres MEDCO_DB_NAME=postgres MEDCO_USER_USERNAME=test MEDCO_USER_PASSWORD=test + + +before_install: + - cd ~/build/ldsec/medco-deployment/resources/data + - bash download.sh + - cd ~/build/ldsec/medco-deployment/compose-profiles/dev-local-3nodes + - docker-compose build + - docker-compose -f docker-compose.tools.yml pull medco-cli-client medco-loader-srv0 medco-loader-srv1 medco-loader-srv2 + +install: + - docker-compose up -d + - bash ~/build/ldsec/medco-deployment/resources/utility-scripts/wait_for_startup.sh $MEDCO_DB_NUMBER $MEDCO_DB_HOST $MEDCO_DB_PORT $MEDCO_DB_USER $MEDCO_DB_PASSWORD $MEDCO_DB_NAME + - docker-compose -f docker-compose.tools.yml run medco-loader-srv0 v0 --ont_clinical /data/genomic/tcga_cbio/8_clinical_data.csv --sen /data/genomic/sensitive.txt --ont_genomic /data/genomic/tcga_cbio/8_mutation_data.csv --clinical /data/genomic/tcga_cbio/8_clinical_data.csv --genomic /data/genomic/tcga_cbio/8_mutation_data.csv --output /data/ + - docker-compose -f docker-compose.tools.yml run medco-loader-srv1 v0 --ont_clinical /data/genomic/tcga_cbio/8_clinical_data.csv --sen /data/genomic/sensitive.txt --ont_genomic /data/genomic/tcga_cbio/8_mutation_data.csv --clinical /data/genomic/tcga_cbio/8_clinical_data.csv --genomic /data/genomic/tcga_cbio/8_mutation_data.csv --output /data/ + - docker-compose -f docker-compose.tools.yml run medco-loader-srv2 v0 --ont_clinical /data/genomic/tcga_cbio/8_clinical_data.csv --sen /data/genomic/sensitive.txt --ont_genomic /data/genomic/tcga_cbio/8_mutation_data.csv --clinical /data/genomic/tcga_cbio/8_clinical_data.csv --genomic /data/genomic/tcga_cbio/8_mutation_data.csv --output /data/ + +script: + - bash ~/build/ldsec/medco-deployment/resources/utility-scripts/test_e2e.sh $MEDCO_USER_USERNAME $MEDCO_USER_PASSWORD \ No newline at end of file diff --git a/README.md b/README.md index 69903d2..b95ee41 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,35 @@ -## Documentation -MedCo documentation is centralized on the following website: -[MedCo Deployment](https://medco.epfl.ch/documentation/developer/components/medco-deployment.html). +## medco-deployment +*medco-deployment* contains the scripts to deploy MedCo in different scenarios. + +A description of the available deployment profiles, along with a detailed guide on how to use them, is available [here](https://ldsec.gitbook.io/medco-documentation/system-administrator-guide/deployment). + +## Source code organization +- *compose-profiles*: docker-compose files and parameters for different deployment profiles + - *[dev-local-3nodes](https://ldsec.gitbook.io/medco-documentation/system-administrator-guide/deployment/local-development-deployment)*: profile that deploys 3 MedCo nodes on a single machine for development purposes + - *[test-local-3nodes](https://ldsec.gitbook.io/medco-documentation/system-administrator-guide/deployment/local-test-deployment)*: profile that deploys 3 MedCo nodes on a single machine for test purposes +- *configuration-profiles*: configuration files for the different deployment profiles (cryptographic keys, certificates, etc.) + - *dev-local-3nodes*: configuration files for the *dev-local-3nodes* profile + - *test-local-3nodes*: configuration files for the *test-local-3nodes* profile +- *docker-images*: configuration files for the docker images that are used in the different deployment profiles + - *i2b2*: configuration files for 12b2 + - *keycloak*: configuration files for keycloak + - *nginx*: configuration files for nginx + - *pgadmin*: configuration files for pgadmin + - *postgresql*: configuration files for postgresql +- *resources*: additional configuration and utility files + - *configuration*: keycloak configuration files + - *data*: script to download the test datasets + - *profile-generation-scripts*: scripts to generate various deployment profiles files + - *test-network*: scripts to generate the deployment profiles files for the [Network Test Deployment](https://ldsec.gitbook.io/medco-documentation/system-administrator-guide/deployment/network-test-deployment) profile + - *utility-scripts*: additional utility scripts + +## Useful information +*medco-deployment* is part of the MedCo system. + +You can find more information about the MedCo project [here](https://medco.epfl.ch/). + +For further details, support, and contacts, you can check the [MedCo Technical Documentation](https://ldsec.gitbook.io/medco-documentation/). ## License -*medco-deployment* is licensed under a End User Software License Agreement ('EULA') for non-commercial use. +*medco-deployment* is licensed under a End User Software License Agreement ('EULA') for non-commercial use. If you need more information, please contact us. diff --git a/compose-profiles/dev-local-3nodes/.env b/compose-profiles/dev-local-3nodes/.env index 31fbb65..3d97132 100644 --- a/compose-profiles/dev-local-3nodes/.env +++ b/compose-profiles/dev-local-3nodes/.env @@ -1,9 +1,7 @@ I2B2_VERSION=dev MEDCO_UNLYNX_VERSION=dev NGINX_VERSION=dev -PHP_FPM_VERSION=dev PGADMIN_VERSION=dev KEYCLOAK_VERSION=dev -PICSURE_VERSION=dev MEDCO_CONNECTOR_VERSION=dev -MEDCO_LOADER_VERSION=dev \ No newline at end of file +MEDCO_LOADER_VERSION=dev diff --git a/compose-profiles/dev-local-3nodes/docker-compose.tools.yml b/compose-profiles/dev-local-3nodes/docker-compose.tools.yml index dcf77cc..ac5bcaf 100644 --- a/compose-profiles/dev-local-3nodes/docker-compose.tools.yml +++ b/compose-profiles/dev-local-3nodes/docker-compose.tools.yml @@ -13,7 +13,8 @@ services: service: medco-loader environment: - LOG_LEVEL=5 - - DB_NAME=i2b2medcosrv0 + - I2B2_DB_NAME=i2b2medcosrv0 + - GA_DB_NAME=gamedcosrv0 - UNLYNX_GROUP_FILE_IDX=0 medco-loader-srv1: @@ -22,7 +23,8 @@ services: service: medco-loader environment: - LOG_LEVEL=5 - - DB_NAME=i2b2medcosrv1 + - I2B2_DB_NAME=i2b2medcosrv1 + - GA_DB_NAME=gamedcosrv1 - UNLYNX_GROUP_FILE_IDX=1 medco-loader-srv2: @@ -31,5 +33,6 @@ services: service: medco-loader environment: - LOG_LEVEL=5 - - DB_NAME=i2b2medcosrv2 + - I2B2_DB_NAME=i2b2medcosrv2 + - GA_DB_NAME=gamedcosrv2 - UNLYNX_GROUP_FILE_IDX=2 diff --git a/compose-profiles/dev-local-3nodes/docker-compose.yml b/compose-profiles/dev-local-3nodes/docker-compose.yml index 047dc39..d1209bc 100644 --- a/compose-profiles/dev-local-3nodes/docker-compose.yml +++ b/compose-profiles/dev-local-3nodes/docker-compose.yml @@ -44,7 +44,12 @@ services: - I2B2_LOGIN_USER=e2etest - I2B2_LOGIN_PASSWORD=e2etest - LOG_LEVEL=5 - - UNLYNX_GROUP_FILE_IDX=0 + - MEDCO_NODE_IDX=0 + - GA_DB_NAME=gamedcosrv0 + - OIDC_JWKS_URLS=http://keycloak:8080/auth/realms/master/protocol/openid-connect/certs,https://medco-demo.epfl.ch/auth/realms/master/protocol/openid-connect/certs + - OIDC_JWT_ISSUERS=http://localhost/auth/realms/master,https://medco-demo.epfl.ch/auth/realms/master + - OIDC_CLIENT_IDS=medco,medco + - OIDC_JWT_USER_ID_CLAIMS=preferred_username,preferred_username networks: intra-node-srv0: inter-nodes: @@ -94,7 +99,12 @@ services: - I2B2_LOGIN_USER=e2etest - I2B2_LOGIN_PASSWORD=e2etest - LOG_LEVEL=5 - - UNLYNX_GROUP_FILE_IDX=1 + - MEDCO_NODE_IDX=1 + - GA_DB_NAME=gamedcosrv1 + - OIDC_JWKS_URLS=http://keycloak:8080/auth/realms/master/protocol/openid-connect/certs,https://medco-demo.epfl.ch/auth/realms/master/protocol/openid-connect/certs + - OIDC_JWT_ISSUERS=http://localhost/auth/realms/master,https://medco-demo.epfl.ch/auth/realms/master + - OIDC_CLIENT_IDS=medco,medco + - OIDC_JWT_USER_ID_CLAIMS=preferred_username,preferred_username networks: intra-node-srv1: inter-nodes: @@ -144,7 +154,12 @@ services: - I2B2_LOGIN_USER=e2etest - I2B2_LOGIN_PASSWORD=e2etest - LOG_LEVEL=5 - - UNLYNX_GROUP_FILE_IDX=2 + - MEDCO_NODE_IDX=2 + - GA_DB_NAME=gamedcosrv2 + - OIDC_JWKS_URLS=http://keycloak:8080/auth/realms/master/protocol/openid-connect/certs,https://medco-demo.epfl.ch/auth/realms/master/protocol/openid-connect/certs + - OIDC_JWT_ISSUERS=http://localhost/auth/realms/master,https://medco-demo.epfl.ch/auth/realms/master + - OIDC_CLIENT_IDS=medco,medco + - OIDC_JWT_USER_ID_CLAIMS=preferred_username,preferred_username networks: intra-node-srv2: inter-nodes: @@ -161,19 +176,6 @@ services: inter-nodes: ipv4_address: 172.31.0.200 - php-fpm: - extends: - file: ../docker-compose-definitions.yml - service: php-fpm - environment: - - I2B2_DB_NAME=i2b2medcosrv0 - - I2B2_DOMAIN_NAME=i2b2medcosrv0 - - I2B2_URL=http://i2b2-medco-srv0:8080/i2b2/services - networks: - intra-node-srv0: - inter-nodes: - ipv4_address: 172.31.0.201 - postgresql: extends: file: ../docker-compose-definitions.yml @@ -206,19 +208,6 @@ services: inter-nodes: ipv4_address: 172.31.0.204 - picsure: - extends: - file: ../docker-compose-definitions.yml - service: picsure - ports: - - "8082:8080" - - "9992:9990" - depends_on: - - postgresql - networks: - inter-nodes: - ipv4_address: 172.31.0.205 - networks: inter-nodes: driver: bridge diff --git a/compose-profiles/docker-compose-definitions.yml b/compose-profiles/docker-compose-definitions.yml index 50e8918..cf9a653 100644 --- a/compose-profiles/docker-compose-definitions.yml +++ b/compose-profiles/docker-compose-definitions.yml @@ -1,7 +1,7 @@ version: '2.4' services: i2b2: - image: medco/i2b2:${I2B2_VERSION:-MedCo-v0.2.1} + image: medco/i2b2:${I2B2_VERSION:-MedCo-v0.3.0} build: context: ../docker-images/i2b2 environment: @@ -9,7 +9,7 @@ services: - I2B2_DB_PORT=5432 - I2B2_DB_USER=i2b2 - I2B2_DB_PW=i2b2 - - I2B2_DB_NAME=i2b2medco + - I2B2_DB_NAME=i2b2medcosrv - WILDFLY_ADMIN_PASSWORD=admin - I2B2_DOMAIN_NAME=i2b2medco - I2B2_SERVICE_PASSWORD=pFjy3EjDVwLfT2rB9xkK @@ -17,7 +17,7 @@ services: - AXIS2_LOGLEVEL=INFO medco-unlynx: - image: medco/medco-unlynx:${MEDCO_UNLYNX_VERSION:-v0.2.1} + image: medco/medco-unlynx:${MEDCO_UNLYNX_VERSION:-v0.3.0} ports: - "2000" - "2001" @@ -28,10 +28,9 @@ services: - ../configuration-profiles/dev-local-3nodes:/medco-configuration nginx: - image: medco/nginx:${NGINX_VERSION:-MedCo-v0.2.1} + image: medco/nginx:${NGINX_VERSION:-MedCo-v0.3.0} build: - context: ../docker-images/web - dockerfile: nginx.Dockerfile + context: ../docker-images/nginx ports: - "80" - "443" @@ -39,27 +38,10 @@ services: - HTTP_SCHEME=http - ALL_TIMEOUTS_SECONDS=600 volumes: - - ../docker-images/web/www-data:/www-data - - ../docker-images/web/nginx-conf.d:/etc/nginx/conf.d + - ../docker-images/nginx/www-data:/www-data + - ../docker-images/nginx/conf.d:/etc/nginx/conf.d - ../configuration-profiles/dev-local-3nodes/group.toml:/medco-configuration/group.toml - php-fpm: - image: medco/php-fpm:${PHP_FPM_VERSION:-MedCo-v0.2.1} - build: - context: ../docker-images/web - dockerfile: php-fpm.Dockerfile - environment: - - I2B2_DB_HOST=postgresql - - I2B2_DB_PORT=5432 - - I2B2_DB_USER=i2b2 - - I2B2_DB_PW=i2b2 - - I2B2_DB_NAME=i2b2medco - - I2B2_DOMAIN_NAME=i2b2medco - - I2B2_URL=http://i2b2:8080/i2b2/services - - CORS_ALLOW_ORIGIN=http://localhost:4200 - volumes: - - ../docker-images/web/www-data:/www-data - postgresql: image: postgres:9.6 environment: @@ -70,7 +52,7 @@ services: - ../docker-images/postgresql/initdb-data:/docker-entrypoint-initdb.d pg-admin: - image: medco/pgadmin4:${PGADMIN_VERSION:-MedCo-v0.2.1} + image: medco/pgadmin4:${PGADMIN_VERSION:-MedCo-v0.3.0} build: context: ../docker-images/pgadmin environment: @@ -78,7 +60,7 @@ services: - PGADMIN_DEFAULT_PASSWORD=admin keycloak: - image: medco/keycloak:${KEYCLOAK_VERSION:-MedCo-v0.2.1} + image: medco/keycloak:${KEYCLOAK_VERSION:-MedCo-v0.3.0} build: context: ../docker-images/keycloak environment: @@ -92,43 +74,18 @@ services: - DB_PASSWORD=keycloak glowing-bear-medco: - image: medco/glowing-bear-medco:${GLOWING_BEAR_MEDCO_VERSION:-v0.2.1} + image: medco/glowing-bear-medco:${GLOWING_BEAR_MEDCO_VERSION:-v0.3.0} ports: - "80" environment: - - GB_API_URL=http://localhost/pic-sure-api-2/PICSURE - - GB_URL=http://localhost:82 - - GB_OIDC_URL=http://localhost/auth/realms/master/protocol/openid-connect - - GB_OIDC_CLIENT_ID=medco - - GB_COTHORITY_KEY_URL=http://localhost/cothority-key.pub.toml - - GB_GENOMIC_ANNOTATIONS_URL=http://localhost/genomicAnnotations - - GB_MEDCO_RESULTS_RANDOMIZATION=0 + - GB_MEDCO_NODE_URL=http://localhost/local-3nodes/medco-0 + - GB_KEYCLOAK_URL=http://localhost/auth + - GB_KEYCLOAK_REALM=master + - GB_KEYCLOAK_CLIENT_ID=medco - GB_FOOTER_TEXT= - - MEDCO_NETWORK_NAME=testnetwork - - MEDCO_NODES_NAME=a,b,c - - picsure: - image: medco/picsure:${PICSURE_VERSION:-MedCo-v0.2.1} - build: - context: ../docker-images/picsure - environment: - - PICSURE2_PGDB_ADDRESS=postgresql - - PICSURE2_PGDB_PORT=5432 - - PICSURE2_PGDB_DB=picsure - - PICSURE2_PGDB_USER=picsure - - PICSURE2_PGDB_PW=picsure - - VERIFY_USER_METHOD=local_jwks - - PICSURE2_USER_ID_CLAIM=preferred_username - - PICSURE2_CLIENT_SECRET=none - - PICSURE2_JWKS_URL=http://keycloak:8080/auth/realms/master/protocol/openid-connect/certs - - PICSURE2_CLIENT_ID=medco - - MEDCO_NETWORK_NAME=testnetwork - - MEDCO_NODES_NAME=a,b,c - - MEDCO_NODES_CONNECTOR_URL=http://medco-connector-srv0:1999/medco-connector/picsure2,http://medco-connector-srv1:1999/medco-connector/picsure2,http://medco-connector-srv2:1999/medco-connector/picsure2 - - HTTP_CLIENT_TIMEOUT_SECONDS=600 medco-connector: - image: medco/medco-connector:${MEDCO_CONNECTOR_VERSION:-v0.2.1} + image: medco/medco-connector:${MEDCO_CONNECTOR_VERSION:-v0.3.0} ports: - "1999" environment: @@ -141,44 +98,55 @@ services: - I2B2_WAIT_TIME_SECONDS=450 - LOG_LEVEL=3 - UNLYNX_GROUP_FILE_PATH=/medco-configuration/group.toml - - UNLYNX_GROUP_FILE_IDX=0 - UNLYNX_TIMEOUT_SECONDS=150 - - JWKS_URL=http://keycloak:8080/auth/realms/master/protocol/openid-connect/certs - - OIDC_JWT_ISSUER=http://localhost/auth/realms/master - - OIDC_CLIENT_ID=medco - - OIDC_JWT_USER_ID_CLAIM=preferred_username + - OIDC_JWKS_URLS=http://keycloak:8080/auth/realms/master/protocol/openid-connect/certs + - OIDC_JWT_ISSUERS=http://localhost/auth/realms/master + - OIDC_CLIENT_IDS=medco + - OIDC_JWT_USER_ID_CLAIMS=preferred_username + - OIDC_JWKS_TIMEOUT_SECONDS=30 - MEDCO_OBFUSCATION_MIN=5 + - MEDCO_NODES_URL=http://localhost/local-3nodes/medco-0,http://localhost/local-3nodes/medco-1,http://localhost/local-3nodes/medco-2 + - MEDCO_NODE_IDX=0 + - GA_DB_HOST=postgresql + - GA_DB_PORT=5432 + - GA_DB_USER=genomicannotations + - GA_DB_PW=genomicannotations + - GA_DB_NAME=gamedco volumes: - ../configuration-profiles/dev-local-3nodes:/medco-configuration medco-cli-client: - image: medco/medco-cli-client:${MEDCO_CONNECTOR_VERSION:-v0.2.1} + image: medco/medco-cli-client:${MEDCO_CONNECTOR_VERSION:-v0.3.0} environment: - LOG_LEVEL=3 - UNLYNX_GROUP_FILE_PATH=/medco-configuration/group.toml - - UNLYNX_GROUP_FILE_IDX=0 - - OIDC_CLIENT_ID=medco + - MEDCO_NODE_IDX=0 - CLIENT_QUERY_TIMEOUT_SECONDS=660 - - PICSURE2_API_HOST=localhost - - PICSURE2_API_BASE_PATH=/pic-sure-api-2/PICSURE - - PICSURE2_API_SCHEME=http - - PICSURE2_RESOURCES=MEDCO_testnetwork_0_a,MEDCO_testnetwork_1_b,MEDCO_testnetwork_2_c + - CLIENT_GENOMIC_ANNOTATIONS_QUERY_TIMEOUT_SECONDS=10 + - MEDCO_CONNECTOR_URL=http://localhost/local-3nodes/medco-0 - OIDC_REQ_TOKEN_URL=http://localhost/auth/realms/master/protocol/openid-connect/token + - OIDC_REQ_TOKEN_CLIENT_ID=medco volumes: - ../configuration-profiles/dev-local-3nodes:/medco-configuration + - ./:/results network_mode: host medco-loader: - image: medco/medco-loader:${MEDCO_LOADER_VERSION:-v0.2.1} + image: medco/medco-loader:${MEDCO_LOADER_VERSION:-v0.3.0} environment: - LOG_LEVEL=3 - UNLYNX_GROUP_FILE_PATH=/medco-configuration/group.toml - UNLYNX_GROUP_FILE_IDX=0 - - DB_HOST=localhost - - DB_PORT=5432 - - DB_NAME=i2b2medco - - DB_USER=i2b2 - - DB_PASSWORD=i2b2 + - I2B2_DB_HOST=localhost + - I2B2_DB_PORT=5432 + - I2B2_DB_NAME=i2b2medco + - I2B2_DB_USER=i2b2 + - I2B2_DB_PASSWORD=i2b2 + - GA_DB_HOST=localhost + - GA_DB_PORT=5432 + - GA_DB_NAME=gamedco + - GA_DB_USER=genomicannotations + - GA_DB_PASSWORD=genomicannotations volumes: - ../resources/data:/data - ../configuration-profiles/dev-local-3nodes:/medco-configuration diff --git a/compose-profiles/test-local-3nodes/docker-compose.tools.yml b/compose-profiles/test-local-3nodes/docker-compose.tools.yml index 331e9c4..33023b0 100644 --- a/compose-profiles/test-local-3nodes/docker-compose.tools.yml +++ b/compose-profiles/test-local-3nodes/docker-compose.tools.yml @@ -5,9 +5,8 @@ services: file: ../docker-compose-definitions.yml service: medco-cli-client environment: - - PICSURE2_API_HOST=${MEDCO_NODE_HOST:?} - - PICSURE2_API_SCHEME=${MEDCO_NODE_HTTP_SCHEME:?} - OIDC_REQ_TOKEN_URL=${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/auth/realms/master/protocol/openid-connect/token + - MEDCO_CONNECTOR_URL=${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/local-3nodes/medco-0 volumes: - ../../configuration-profiles/test-local-3nodes:/medco-configuration @@ -16,9 +15,11 @@ services: file: ../docker-compose-definitions.yml service: medco-loader environment: - - DB_NAME=i2b2medcosrv0 + - I2B2_DB_NAME=i2b2medcosrv0 + - GA_DB_NAME=gamedcosrv0 - UNLYNX_GROUP_FILE_IDX=0 - - DB_HOST=${MEDCO_NODE_HOST:?} + - I2B2_DB_HOST=${MEDCO_NODE_HOST:?} + - GA_DB_HOST=${MEDCO_NODE_HOST:?} volumes: - ../../configuration-profiles/test-local-3nodes:/medco-configuration @@ -27,9 +28,11 @@ services: file: ../docker-compose-definitions.yml service: medco-loader environment: - - DB_NAME=i2b2medcosrv1 + - I2B2_DB_NAME=i2b2medcosrv1 + - GA_DB_NAME=gamedcosrv1 - UNLYNX_GROUP_FILE_IDX=1 - - DB_HOST=${MEDCO_NODE_HOST:?} + - I2B2_DB_HOST=${MEDCO_NODE_HOST:?} + - GA_DB_HOST=${MEDCO_NODE_HOST:?} volumes: - ../../configuration-profiles/test-local-3nodes:/medco-configuration @@ -38,8 +41,10 @@ services: file: ../docker-compose-definitions.yml service: medco-loader environment: - - DB_NAME=i2b2medcosrv2 + - I2B2_DB_NAME=i2b2medcosrv2 + - GA_DB_NAME=gamedcosrv0 - UNLYNX_GROUP_FILE_IDX=2 - - DB_HOST=${MEDCO_NODE_HOST:?} + - I2B2_DB_HOST=${MEDCO_NODE_HOST:?} + - GA_DB_HOST=${MEDCO_NODE_HOST:?} volumes: - ../../configuration-profiles/test-local-3nodes:/medco-configuration diff --git a/compose-profiles/test-local-3nodes/docker-compose.yml b/compose-profiles/test-local-3nodes/docker-compose.yml index 580f642..1a8cb46 100644 --- a/compose-profiles/test-local-3nodes/docker-compose.yml +++ b/compose-profiles/test-local-3nodes/docker-compose.yml @@ -7,7 +7,6 @@ services: environment: - I2B2_DB_NAME=i2b2medcosrv0 - I2B2_DOMAIN_NAME=i2b2medcosrv0 - - NODE_IDX=0 - WILDFLY_ADMIN_PASSWORD=${I2B2_WILDFLY_PASSWORD:?} - I2B2_SERVICE_PASSWORD=${I2B2_SERVICE_PASSWORD:?} - DEFAULT_USER_PASSWORD=${I2B2_USER_PASSWORD:?} @@ -44,9 +43,14 @@ services: environment: - I2B2_HIVE_URL=http://i2b2-srv0:8080/i2b2/services - I2B2_LOGIN_DOMAIN=i2b2medcosrv0 - - UNLYNX_GROUP_FILE_IDX=0 - - OIDC_JWT_ISSUER=${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/auth/realms/master + - MEDCO_NODE_IDX=0 + - OIDC_JWT_ISSUERS=${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/auth/realms/master - I2B2_LOGIN_PASSWORD=${I2B2_USER_PASSWORD:?} + - GA_DB_NAME=gamedcosrv0 + - "MEDCO_NODES_URL=\ + ${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/local-3nodes/medco-0,\ + ${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/local-3nodes/medco-1,\ + ${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/local-3nodes/medco-2" networks: intra-node-srv0: inter-nodes: @@ -60,7 +64,6 @@ services: environment: - I2B2_DB_NAME=i2b2medcosrv1 - I2B2_DOMAIN_NAME=i2b2medcosrv1 - - NODE_IDX=1 - WILDFLY_ADMIN_PASSWORD=${I2B2_WILDFLY_PASSWORD:?} - I2B2_SERVICE_PASSWORD=${I2B2_SERVICE_PASSWORD:?} - DEFAULT_USER_PASSWORD=${I2B2_USER_PASSWORD:?} @@ -97,9 +100,14 @@ services: environment: - I2B2_HIVE_URL=http://i2b2-srv1:8080/i2b2/services - I2B2_LOGIN_DOMAIN=i2b2medcosrv1 - - UNLYNX_GROUP_FILE_IDX=1 - - OIDC_JWT_ISSUER=${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/auth/realms/master + - MEDCO_NODE_IDX=1 + - OIDC_JWT_ISSUERS=${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/auth/realms/master - I2B2_LOGIN_PASSWORD=${I2B2_USER_PASSWORD:?} + - GA_DB_NAME=gamedcosrv1 + - "MEDCO_NODES_URL=\ + ${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/local-3nodes/medco-0,\ + ${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/local-3nodes/medco-1,\ + ${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/local-3nodes/medco-2" networks: intra-node-srv1: inter-nodes: @@ -113,7 +121,6 @@ services: environment: - I2B2_DB_NAME=i2b2medcosrv2 - I2B2_DOMAIN_NAME=i2b2medcosrv2 - - NODE_IDX=2 - WILDFLY_ADMIN_PASSWORD=${I2B2_WILDFLY_PASSWORD:?} - I2B2_SERVICE_PASSWORD=${I2B2_SERVICE_PASSWORD:?} - DEFAULT_USER_PASSWORD=${I2B2_USER_PASSWORD:?} @@ -150,9 +157,14 @@ services: environment: - I2B2_HIVE_URL=http://i2b2-srv2:8080/i2b2/services - I2B2_LOGIN_DOMAIN=i2b2medcosrv2 - - UNLYNX_GROUP_FILE_IDX=2 - - OIDC_JWT_ISSUER=${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/auth/realms/master + - MEDCO_NODE_IDX=2 + - OIDC_JWT_ISSUERS=${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/auth/realms/master - I2B2_LOGIN_PASSWORD=${I2B2_USER_PASSWORD:?} + - GA_DB_NAME=gamedcosrv2 + - "MEDCO_NODES_URL=\ + ${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/local-3nodes/medco-0,\ + ${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/local-3nodes/medco-1,\ + ${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/local-3nodes/medco-2" networks: intra-node-srv2: inter-nodes: @@ -166,13 +178,9 @@ services: ports: - "82:80" environment: - - GB_API_URL=${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/pic-sure-api-2/PICSURE - - GB_URL=${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/glowing-bear - - GB_OIDC_URL=${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/auth/realms/master/protocol/openid-connect - - GB_OIDC_CLIENT_ID=medco - - GB_COTHORITY_KEY_URL=${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/cothority-key.pub.toml - - GB_GENOMIC_ANNOTATIONS_URL=${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/genomicAnnotations - - GB_MEDCO_RESULTS_RANDOMIZATION=0 + - GB_MEDCO_NODE_URL=${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/local-3nodes/medco-0 + - GB_KEYCLOAK_URL=${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?}/auth + - GB_FOOTER_TEXT= networks: inter-nodes: @@ -193,19 +201,6 @@ services: - ../../configuration-profiles/test-local-3nodes/certificate.crt:/medco-configuration/certificate.crt - ../../configuration-profiles/test-local-3nodes/certificate.key:/medco-configuration/certificate.key - php-fpm: - extends: - file: ../docker-compose-definitions.yml - service: php-fpm - environment: - - I2B2_DB_NAME=i2b2medcosrv0 - - I2B2_DOMAIN_NAME=i2b2medcosrv0 - - I2B2_URL=http://i2b2-medco-srv0:8080/i2b2/services - - CORS_ALLOW_ORIGIN=${MEDCO_NODE_HTTP_SCHEME:?}://${MEDCO_NODE_HOST:?} - networks: - intra-node-srv0: - inter-nodes: - postgresql: extends: file: ../docker-compose-definitions.yml @@ -241,18 +236,6 @@ services: networks: inter-nodes: - picsure: - extends: - file: ../docker-compose-definitions.yml - service: picsure - ports: - - "8082:8080" - - "9992:9990" - depends_on: - - postgresql - networks: - inter-nodes: - networks: inter-nodes: driver: bridge diff --git a/docker-images/i2b2/docker-entrypoint.sh b/docker-images/i2b2/docker-entrypoint.sh index 83a71d6..8134a7d 100644 --- a/docker-images/i2b2/docker-entrypoint.sh +++ b/docker-images/i2b2/docker-entrypoint.sh @@ -10,7 +10,7 @@ until psql $PSQL_PARAMS -d postgres -c '\q'; do done # load initial data if database does not exist (credentials must be valid and have create database right) -DB_CHECK=`psql ${PSQL_PARAMS} -d postgres -X -A -t -c "select count(*) from pg_database where datname = '${I2B2_DB_NAME}';"` +DB_CHECK=$(psql ${PSQL_PARAMS} -d postgres -X -A -t -c "select count(*) from pg_database where datname = '${I2B2_DB_NAME}';") if [[ "$DB_CHECK" -ne "1" ]]; then echo "Initialising i2b2 database" psql $PSQL_PARAMS -d postgres <<-EOSQL @@ -19,7 +19,7 @@ EOSQL # get the i2b2 data pushd "$I2B2_DATA_DIR" - git clone --depth 1 --branch $I2B2_DATA_VERSION https://github.com/i2b2/i2b2-data.git . + git clone --depth 1 --branch "$I2B2_DATA_VERSION" https://github.com/i2b2/i2b2-data.git . popd # run loading scripts diff --git a/docker-images/i2b2/sql/50-medco-schemas.sh b/docker-images/i2b2/sql/50-medco-schemas.sh index 1ffa4a9..0012b9b 100644 --- a/docker-images/i2b2/sql/50-medco-schemas.sh +++ b/docker-images/i2b2/sql/50-medco-schemas.sh @@ -14,4 +14,3 @@ EOSQL # init demo i2b2 database initSchema $I2B2_DB_NAME medco_ont -initSchema $I2B2_DB_NAME genomic_annotations diff --git a/docker-images/keycloak/Dockerfile b/docker-images/keycloak/Dockerfile index 0aaad2b..aba3732 100644 --- a/docker-images/keycloak/Dockerfile +++ b/docker-images/keycloak/Dockerfile @@ -3,6 +3,7 @@ FROM jboss/keycloak:6.0.1 USER root COPY proxy-update.cli /opt/jboss/tools/cli/ +COPY default-medco-realm.json / # invoke configuration commands to take into account the change in build-time environment variable ENV PROXY_ADDRESS_FORWARDING="true" @@ -13,3 +14,8 @@ RUN cd /opt/jboss/keycloak && \ chmod -R g+rw /opt/jboss/keycloak USER 1000 +CMD ["-b", "0.0.0.0", \ + "-Dkeycloak.migration.action=import", \ + "-Dkeycloak.migration.provider=singleFile", \ + "-Dkeycloak.migration.strategy=IGNORE_EXISTING", \ + "-Dkeycloak.migration.file=/default-medco-realm.json"] diff --git a/docker-images/keycloak/default-medco-realm.json b/docker-images/keycloak/default-medco-realm.json new file mode 100644 index 0000000..89c27bf --- /dev/null +++ b/docker-images/keycloak/default-medco-realm.json @@ -0,0 +1,1591 @@ +{ + "id" : "master", + "realm" : "master", + "displayName" : "Keycloak", + "displayNameHtml" : "
Keycloak
", + "notBefore" : 0, + "revokeRefreshToken" : false, + "refreshTokenMaxReuse" : 0, + "accessTokenLifespan" : 60, + "accessTokenLifespanForImplicitFlow" : 900, + "ssoSessionIdleTimeout" : 1800, + "ssoSessionMaxLifespan" : 36000, + "ssoSessionIdleTimeoutRememberMe" : 0, + "ssoSessionMaxLifespanRememberMe" : 0, + "offlineSessionIdleTimeout" : 2592000, + "offlineSessionMaxLifespanEnabled" : false, + "offlineSessionMaxLifespan" : 5184000, + "accessCodeLifespan" : 60, + "accessCodeLifespanUserAction" : 300, + "accessCodeLifespanLogin" : 1800, + "actionTokenGeneratedByAdminLifespan" : 43200, + "actionTokenGeneratedByUserLifespan" : 300, + "enabled" : true, + "sslRequired" : "external", + "registrationAllowed" : false, + "registrationEmailAsUsername" : false, + "rememberMe" : false, + "verifyEmail" : false, + "loginWithEmailAllowed" : true, + "duplicateEmailsAllowed" : false, + "resetPasswordAllowed" : false, + "editUsernameAllowed" : false, + "bruteForceProtected" : false, + "permanentLockout" : false, + "maxFailureWaitSeconds" : 900, + "minimumQuickLoginWaitSeconds" : 60, + "waitIncrementSeconds" : 60, + "quickLoginCheckMilliSeconds" : 1000, + "maxDeltaTimeSeconds" : 43200, + "failureFactor" : 30, + "roles" : { + "realm" : [ { + "id" : "ff118ef4-12f1-442a-ad1c-c0bbe8ef8568", + "name" : "create-realm", + "description" : "${role_create-realm}", + "composite" : false, + "clientRole" : false, + "containerId" : "master", + "attributes" : { } + }, { + "id" : "3fb3642b-ae85-44b9-ab9e-df229bf29ab8", + "name" : "offline_access", + "description" : "${role_offline-access}", + "composite" : false, + "clientRole" : false, + "containerId" : "master", + "attributes" : { } + }, { + "id" : "f1cdd677-48d9-4fc9-b2eb-bbee1a27a4e3", + "name" : "admin", + "description" : "${role_admin}", + "composite" : true, + "composites" : { + "realm" : [ "create-realm" ], + "client" : { + "master-realm" : [ "create-client", "view-events", "manage-realm", "impersonation", "manage-users", "view-clients", "manage-authorization", "view-identity-providers", "view-authorization", "manage-events", "manage-clients", "manage-identity-providers", "view-users", "query-users", "query-clients", "query-groups", "query-realms", "view-realm" ] + } + }, + "clientRole" : false, + "containerId" : "master", + "attributes" : { } + }, { + "id" : "161ecc69-bee2-4f59-b973-f778482d818f", + "name" : "uma_authorization", + "description" : "${role_uma_authorization}", + "composite" : false, + "clientRole" : false, + "containerId" : "master", + "attributes" : { } + } ], + "client" : { + "security-admin-console" : [ ], + "medco" : [ { + "id" : "a4750c34-edad-4422-8707-07dd865f0b42", + "name" : "medco-explore", + "composite" : false, + "clientRole" : true, + "containerId" : "6aa5311d-383f-402d-bcf2-a1d2ac566f00", + "attributes" : { } + }, { + "id" : "4d0b0eaa-9fc3-43eb-95d5-6ccd40b88d7e", + "name" : "count_per_site", + "composite" : false, + "clientRole" : true, + "containerId" : "6aa5311d-383f-402d-bcf2-a1d2ac566f00", + "attributes" : { } + }, { + "id" : "3d7195ad-c11c-4d40-b7e9-fefdff77b38b", + "name" : "count_per_site_shuffled", + "composite" : false, + "clientRole" : true, + "containerId" : "6aa5311d-383f-402d-bcf2-a1d2ac566f00", + "attributes" : { } + }, { + "id" : "47ca783d-3257-4d60-9029-622961c73cf7", + "name" : "medco-genomic-annotations", + "composite" : false, + "clientRole" : true, + "containerId" : "6aa5311d-383f-402d-bcf2-a1d2ac566f00", + "attributes" : { } + }, { + "id" : "687e26a2-6f72-425b-827f-4fc779b88d83", + "name" : "patient_list", + "composite" : false, + "clientRole" : true, + "containerId" : "6aa5311d-383f-402d-bcf2-a1d2ac566f00", + "attributes" : { } + }, { + "id" : "b80712cd-2cde-48eb-a5f8-7a2b5f93763c", + "name" : "count_global_obfuscated", + "composite" : false, + "clientRole" : true, + "containerId" : "6aa5311d-383f-402d-bcf2-a1d2ac566f00", + "attributes" : { } + }, { + "id" : "a6e00688-b304-4033-8d50-ab6e1ab0467f", + "name" : "medco-network", + "composite" : false, + "clientRole" : true, + "containerId" : "6aa5311d-383f-402d-bcf2-a1d2ac566f00", + "attributes" : { } + }, { + "id" : "573c96f2-070f-4c91-87c3-2dd8d9fb6107", + "name" : "count_per_site_obfuscated", + "composite" : false, + "clientRole" : true, + "containerId" : "6aa5311d-383f-402d-bcf2-a1d2ac566f00", + "attributes" : { } + }, { + "id" : "b6110ee3-f686-4e20-be95-8b48a10b88f8", + "name" : "count_per_site_shuffled_obfuscated", + "composite" : false, + "clientRole" : true, + "containerId" : "6aa5311d-383f-402d-bcf2-a1d2ac566f00", + "attributes" : { } + }, { + "id" : "508216a4-bc96-4687-bf61-98bac32790b5", + "name" : "count_global", + "composite" : false, + "clientRole" : true, + "containerId" : "6aa5311d-383f-402d-bcf2-a1d2ac566f00", + "attributes" : { } + } ], + "admin-cli" : [ ], + "broker" : [ { + "id" : "c8353ed5-77de-4048-bb7f-41dd3af1af98", + "name" : "read-token", + "description" : "${role_read-token}", + "composite" : false, + "clientRole" : true, + "containerId" : "e90a1889-23ae-43d1-babd-ec5ec3ff093c", + "attributes" : { } + } ], + "master-realm" : [ { + "id" : "fd76d27e-7632-4864-a4fd-861574f40b7b", + "name" : "create-client", + "description" : "${role_create-client}", + "composite" : false, + "clientRole" : true, + "containerId" : "33b5bc05-5aaf-447e-8916-e5a1991ef418", + "attributes" : { } + }, { + "id" : "83991b5f-696b-400d-b650-a2ae22ac8e65", + "name" : "view-events", + "description" : "${role_view-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "33b5bc05-5aaf-447e-8916-e5a1991ef418", + "attributes" : { } + }, { + "id" : "fd0a3a6b-2ca9-44f3-bc9c-e07a500c5955", + "name" : "manage-realm", + "description" : "${role_manage-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "33b5bc05-5aaf-447e-8916-e5a1991ef418", + "attributes" : { } + }, { + "id" : "09d24824-a48c-4799-93b7-7b4e2d03ebd5", + "name" : "impersonation", + "description" : "${role_impersonation}", + "composite" : false, + "clientRole" : true, + "containerId" : "33b5bc05-5aaf-447e-8916-e5a1991ef418", + "attributes" : { } + }, { + "id" : "f38d1227-aa6f-4f50-ad8d-8b19ed7cee6d", + "name" : "manage-users", + "description" : "${role_manage-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "33b5bc05-5aaf-447e-8916-e5a1991ef418", + "attributes" : { } + }, { + "id" : "98d39c53-4572-486e-a5b7-9d6aa0a8335a", + "name" : "view-clients", + "description" : "${role_view-clients}", + "composite" : true, + "composites" : { + "client" : { + "master-realm" : [ "query-clients" ] + } + }, + "clientRole" : true, + "containerId" : "33b5bc05-5aaf-447e-8916-e5a1991ef418", + "attributes" : { } + }, { + "id" : "ff7fb502-1059-4605-bcb8-015cb5108cfa", + "name" : "manage-authorization", + "description" : "${role_manage-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "33b5bc05-5aaf-447e-8916-e5a1991ef418", + "attributes" : { } + }, { + "id" : "5c4e1efc-12f0-4af2-be72-5044d4b00f7e", + "name" : "view-identity-providers", + "description" : "${role_view-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "33b5bc05-5aaf-447e-8916-e5a1991ef418", + "attributes" : { } + }, { + "id" : "938a219b-4a3c-4e7d-accd-42f5cbc953ec", + "name" : "view-authorization", + "description" : "${role_view-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "33b5bc05-5aaf-447e-8916-e5a1991ef418", + "attributes" : { } + }, { + "id" : "06e5ca05-0d92-4991-b480-a8520653d75f", + "name" : "manage-events", + "description" : "${role_manage-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "33b5bc05-5aaf-447e-8916-e5a1991ef418", + "attributes" : { } + }, { + "id" : "c0b2ee3b-283d-48cc-ba7d-83eddf205367", + "name" : "manage-clients", + "description" : "${role_manage-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "33b5bc05-5aaf-447e-8916-e5a1991ef418", + "attributes" : { } + }, { + "id" : "e10ed9ea-673b-45b9-8c5c-fe20b10bcac6", + "name" : "manage-identity-providers", + "description" : "${role_manage-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "33b5bc05-5aaf-447e-8916-e5a1991ef418", + "attributes" : { } + }, { + "id" : "379e305a-a98b-48de-90a5-3740a8d3440c", + "name" : "view-users", + "description" : "${role_view-users}", + "composite" : true, + "composites" : { + "client" : { + "master-realm" : [ "query-users", "query-groups" ] + } + }, + "clientRole" : true, + "containerId" : "33b5bc05-5aaf-447e-8916-e5a1991ef418", + "attributes" : { } + }, { + "id" : "30d61a05-a78e-4e7c-a97a-69d01754e360", + "name" : "query-users", + "description" : "${role_query-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "33b5bc05-5aaf-447e-8916-e5a1991ef418", + "attributes" : { } + }, { + "id" : "8e03a1c2-a36e-4c08-aee4-314178c0e7bb", + "name" : "query-clients", + "description" : "${role_query-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "33b5bc05-5aaf-447e-8916-e5a1991ef418", + "attributes" : { } + }, { + "id" : "065333c7-21ab-4ecd-bde2-83a1a38383ba", + "name" : "query-groups", + "description" : "${role_query-groups}", + "composite" : false, + "clientRole" : true, + "containerId" : "33b5bc05-5aaf-447e-8916-e5a1991ef418", + "attributes" : { } + }, { + "id" : "8c1ef7be-1c7b-44a6-aec9-d62de17f6159", + "name" : "query-realms", + "description" : "${role_query-realms}", + "composite" : false, + "clientRole" : true, + "containerId" : "33b5bc05-5aaf-447e-8916-e5a1991ef418", + "attributes" : { } + }, { + "id" : "dddb691d-c4eb-4b04-89c6-1c1808405288", + "name" : "view-realm", + "description" : "${role_view-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "33b5bc05-5aaf-447e-8916-e5a1991ef418", + "attributes" : { } + } ], + "account" : [ { + "id" : "16861045-2370-4550-a994-a50995d9773f", + "name" : "manage-account", + "description" : "${role_manage-account}", + "composite" : true, + "composites" : { + "client" : { + "account" : [ "manage-account-links" ] + } + }, + "clientRole" : true, + "containerId" : "f2771f60-467d-4bc9-9c44-cbf6c02c965f", + "attributes" : { } + }, { + "id" : "a7d63f68-d48f-4231-8d48-e94c2befbe15", + "name" : "view-profile", + "description" : "${role_view-profile}", + "composite" : false, + "clientRole" : true, + "containerId" : "f2771f60-467d-4bc9-9c44-cbf6c02c965f", + "attributes" : { } + }, { + "id" : "f39bfcbe-f8b5-47c0-86c2-1023b4615ecd", + "name" : "manage-account-links", + "description" : "${role_manage-account-links}", + "composite" : false, + "clientRole" : true, + "containerId" : "f2771f60-467d-4bc9-9c44-cbf6c02c965f", + "attributes" : { } + } ] + } + }, + "groups" : [ ], + "defaultRoles" : [ "offline_access", "uma_authorization" ], + "requiredCredentials" : [ "password" ], + "otpPolicyType" : "totp", + "otpPolicyAlgorithm" : "HmacSHA1", + "otpPolicyInitialCounter" : 0, + "otpPolicyDigits" : 6, + "otpPolicyLookAheadWindow" : 1, + "otpPolicyPeriod" : 30, + "otpSupportedApplications" : [ "FreeOTP", "Google Authenticator" ], + "users" : [ { + "id" : "ced4947c-f27a-441e-8602-57cf8e462344", + "createdTimestamp" : 1578588512735, + "username" : "keycloak", + "enabled" : true, + "totp" : false, + "emailVerified" : false, + "credentials" : [ { + "type" : "password", + "hashedSaltedValue" : "8Nn1AkCaoJpezgpudgXU6vxlnG44saBRXDuGwnORhtE2SiPKWQpLVgsQULqSipOtdDZY98+uQVF2LvBCyxXT/A==", + "salt" : "Jp1YbkeWnt2Uh+OsnUVwdQ==", + "hashIterations" : 27500, + "counter" : 0, + "algorithm" : "pbkdf2-sha256", + "digits" : 0, + "period" : 0, + "config" : { } + } ], + "disableableCredentialTypes" : [ "password" ], + "requiredActions" : [ ], + "realmRoles" : [ "offline_access", "admin", "uma_authorization" ], + "clientRoles" : { + "account" : [ "manage-account", "view-profile" ] + }, + "notBefore" : 0, + "groups" : [ ] + }, { + "id" : "e1cf81b1-c29f-4e8f-bb1c-cd3a0c682922", + "createdTimestamp" : 1578656025710, + "username" : "test", + "enabled" : true, + "totp" : false, + "emailVerified" : true, + "credentials" : [ { + "type" : "password", + "hashedSaltedValue" : "BrXt53QkbYpunrZjQuc7jstNfeKRb4BApHB1t6Og6UtwKABj3x7pVIQ50mXXZLEXd7RDgTP1vO/lmJZZMkEl8Q==", + "salt" : "z5295zlQXDzHG4iAiv4RVg==", + "hashIterations" : 27500, + "counter" : 0, + "algorithm" : "pbkdf2-sha256", + "digits" : 0, + "period" : 0, + "createdDate" : 1578656041942, + "config" : { } + } ], + "disableableCredentialTypes" : [ "password" ], + "requiredActions" : [ ], + "realmRoles" : [ "offline_access", "uma_authorization" ], + "clientRoles" : { + "medco" : [ "count_per_site", "patient_list", "count_global_obfuscated", "medco-explore", "count_per_site_shuffled", "medco-genomic-annotations", "medco-network", "count_per_site_shuffled_obfuscated", "count_per_site_obfuscated", "count_global" ], + "account" : [ "manage-account", "view-profile" ] + }, + "notBefore" : 0, + "groups" : [ ] + } ], + "scopeMappings" : [ { + "clientScope" : "offline_access", + "roles" : [ "offline_access" ] + } ], + "clients" : [ { + "id" : "f2771f60-467d-4bc9-9c44-cbf6c02c965f", + "clientId" : "account", + "name" : "${client_account}", + "baseUrl" : "/auth/realms/master/account", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "7dbceb1a-f6f0-47eb-bb23-bcacbc26b751", + "defaultRoles" : [ "view-profile", "manage-account" ], + "redirectUris" : [ "/auth/realms/master/account/*" ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "role_list", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "b3509e7e-f6ae-435d-8fdd-3081deb93251", + "clientId" : "admin-cli", + "name" : "${client_admin-cli}", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "ba268fac-d423-40c6-ab52-ee6a9a1cd6cd", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : false, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : true, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "role_list", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "e90a1889-23ae-43d1-babd-ec5ec3ff093c", + "clientId" : "broker", + "name" : "${client_broker}", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "8022d36b-7920-4050-bc5d-4d9a485b088a", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "role_list", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "33b5bc05-5aaf-447e-8916-e5a1991ef418", + "clientId" : "master-realm", + "name" : "master Realm", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "428b7e41-8009-482c-9d69-8275cc207048", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : true, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "attributes" : { }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : true, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "role_list", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "6aa5311d-383f-402d-bcf2-a1d2ac566f00", + "clientId" : "medco", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "**********", + "redirectUris" : [ "http://localhost:4200/*", "http://localhost/*" ], + "webOrigins" : [ "+" ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : true, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "saml.assertion.signature" : "false", + "saml.force.post.binding" : "false", + "saml.multivalued.roles" : "false", + "saml.encrypt" : "false", + "saml.server.signature" : "false", + "saml.server.signature.keyinfo.ext" : "false", + "exclude.session.state.from.auth.response" : "false", + "saml_force_name_id_format" : "false", + "saml.client.signature" : "false", + "tls.client.certificate.bound.access.tokens" : "false", + "saml.authnstatement" : "false", + "display.on.consent.screen" : "false", + "saml.onetimeuse.condition" : "false" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : true, + "nodeReRegistrationTimeout" : -1, + "protocolMappers" : [ { + "id" : "d8b71bea-039e-4f05-b81c-81671dbb71b6", + "name" : "MedCo Audience", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-audience-mapper", + "consentRequired" : false, + "config" : { + "included.client.audience" : "medco", + "id.token.claim" : "false", + "access.token.claim" : "true", + "userinfo.token.claim" : "false" + } + } ], + "defaultClientScopes" : [ "web-origins", "role_list", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access" ] + }, { + "id" : "272027c9-2050-48ef-9db4-a04bbee9cb16", + "clientId" : "security-admin-console", + "name" : "${client_security-admin-console}", + "baseUrl" : "/auth/admin/master/console/index.html", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "8b080672-a39e-4a1b-917a-15136388f234", + "redirectUris" : [ "/auth/admin/master/console/*" ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "daee02b0-90a8-4fa6-9cc6-4a60e4456618", + "name" : "locale", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "locale", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "locale", + "jsonType.label" : "String" + } + } ], + "defaultClientScopes" : [ "web-origins", "role_list", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + } ], + "clientScopes" : [ { + "id" : "f52d41ea-4be9-435f-95c1-a80286305082", + "name" : "microprofile-jwt", + "description" : "Microprofile - JWT built-in scope", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "false" + }, + "protocolMappers" : [ { + "id" : "ec5af23f-f245-4520-9d87-8715bfad03cc", + "name" : "upn", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "upn", + "jsonType.label" : "String" + } + }, { + "id" : "6ce8e66f-76e0-4919-94f4-c8fb02cbbae9", + "name" : "groups", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-realm-role-mapper", + "consentRequired" : false, + "config" : { + "multivalued" : "true", + "user.attribute" : "foo", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "groups", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "c64619f9-9f46-4787-9e2a-d351ec1fcc53", + "name" : "web-origins", + "description" : "OpenID Connect scope for add allowed web origins to the access token", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "false", + "display.on.consent.screen" : "false", + "consent.screen.text" : "" + }, + "protocolMappers" : [ { + "id" : "25288381-dd5a-4fee-95f4-f191488ef710", + "name" : "allowed web origins", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-allowed-origins-mapper", + "consentRequired" : false, + "config" : { } + } ] + }, { + "id" : "6f3f1141-1565-4f20-ae27-d1ebb570914b", + "name" : "roles", + "description" : "OpenID Connect scope for add user roles to the access token", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "false", + "display.on.consent.screen" : "true", + "consent.screen.text" : "${rolesScopeConsentText}" + }, + "protocolMappers" : [ { + "id" : "98385cee-54a6-4754-8da7-bbcd97e90821", + "name" : "audience resolve", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-audience-resolve-mapper", + "consentRequired" : false, + "config" : { } + }, { + "id" : "a288edf1-3ea8-4c2f-9311-11b039e2c730", + "name" : "client roles", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-client-role-mapper", + "consentRequired" : false, + "config" : { + "user.attribute" : "foo", + "access.token.claim" : "true", + "claim.name" : "resource_access.${client_id}.roles", + "jsonType.label" : "String", + "multivalued" : "true" + } + }, { + "id" : "0153a652-12bd-4397-a0d7-2c810bcdfff1", + "name" : "realm roles", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-realm-role-mapper", + "consentRequired" : false, + "config" : { + "user.attribute" : "foo", + "access.token.claim" : "true", + "claim.name" : "realm_access.roles", + "jsonType.label" : "String", + "multivalued" : "true" + } + } ] + }, { + "id" : "5930dff9-aa07-42f6-b4e9-e6e6ee39c39e", + "name" : "phone", + "description" : "OpenID Connect built-in scope: phone", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "true", + "consent.screen.text" : "${phoneScopeConsentText}" + }, + "protocolMappers" : [ { + "id" : "50659187-5d2b-4250-817b-c0b10b295ab0", + "name" : "phone number verified", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "phoneNumberVerified", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "phone_number_verified", + "jsonType.label" : "boolean" + } + }, { + "id" : "0c9f213f-cd60-4bac-b35f-d2ebb524196b", + "name" : "phone number", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "phoneNumber", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "phone_number", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "9fc89fba-9f02-41b5-a300-0282126d7319", + "name" : "address", + "description" : "OpenID Connect built-in scope: address", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "true", + "consent.screen.text" : "${addressScopeConsentText}" + }, + "protocolMappers" : [ { + "id" : "9de1f1b5-0c5b-4eb5-a752-6e4c2cb69c59", + "name" : "address", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-address-mapper", + "consentRequired" : false, + "config" : { + "user.attribute.formatted" : "formatted", + "user.attribute.country" : "country", + "user.attribute.postal_code" : "postal_code", + "userinfo.token.claim" : "true", + "user.attribute.street" : "street", + "id.token.claim" : "true", + "user.attribute.region" : "region", + "access.token.claim" : "true", + "user.attribute.locality" : "locality" + } + } ] + }, { + "id" : "80955d1f-4199-4a1c-90ae-6e190a605627", + "name" : "email", + "description" : "OpenID Connect built-in scope: email", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "true", + "consent.screen.text" : "${emailScopeConsentText}" + }, + "protocolMappers" : [ { + "id" : "a4c38eb9-0d43-4f67-b093-4398e1707613", + "name" : "email verified", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "emailVerified", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email_verified", + "jsonType.label" : "boolean" + } + }, { + "id" : "8f27477c-a63f-439f-8dbb-703ba9627964", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "af209c47-b526-41fa-9786-18df96c08781", + "name" : "profile", + "description" : "OpenID Connect built-in scope: profile", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "true", + "consent.screen.text" : "${profileScopeConsentText}" + }, + "protocolMappers" : [ { + "id" : "5c7c1967-e086-44e2-a5f4-62e013d03e91", + "name" : "updated at", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "updatedAt", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "updated_at", + "jsonType.label" : "String" + } + }, { + "id" : "09487306-f987-4a6d-8c30-e9bfb01bfe7e", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "4fdef985-0e37-4006-beb6-2a80a026e96c", + "name" : "gender", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "gender", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "gender", + "jsonType.label" : "String" + } + }, { + "id" : "372492e5-5853-41e7-8505-3604057bffe3", + "name" : "locale", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "locale", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "locale", + "jsonType.label" : "String" + } + }, { + "id" : "1c7c4e0a-ac52-43fc-9eb2-9cf9e710e2a5", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : false, + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true", + "userinfo.token.claim" : "true" + } + }, { + "id" : "1bcebd0e-e2be-4504-b577-cf5024b2daa2", + "name" : "picture", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "picture", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "picture", + "jsonType.label" : "String" + } + }, { + "id" : "1f323d8e-c10a-4f1e-b7fb-ff25a691f674", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "fe66baf5-f6b5-4f25-b67a-cb6b5da0bef3", + "name" : "middle name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "middleName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "middle_name", + "jsonType.label" : "String" + } + }, { + "id" : "fdbedc07-d167-4dc5-81eb-a769d86f757b", + "name" : "website", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "website", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "website", + "jsonType.label" : "String" + } + }, { + "id" : "ca3be2af-7eae-4990-9687-aaea2aa39e17", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "a13ec1a4-2fb6-4a61-a4f6-7b32da378add", + "name" : "birthdate", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "birthdate", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "birthdate", + "jsonType.label" : "String" + } + }, { + "id" : "28c090d2-d83d-4113-ab15-18c283194b03", + "name" : "nickname", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "nickname", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "nickname", + "jsonType.label" : "String" + } + }, { + "id" : "d45981d1-f04b-48c1-8369-e3e9d23187bb", + "name" : "profile", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "profile", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "profile", + "jsonType.label" : "String" + } + }, { + "id" : "72ed7b67-e641-44b2-aa2f-daea9498f7b9", + "name" : "zoneinfo", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "zoneinfo", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "zoneinfo", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "6a0b0ed1-6c3e-4637-8acf-5f1972177214", + "name" : "role_list", + "description" : "SAML role list", + "protocol" : "saml", + "attributes" : { + "consent.screen.text" : "${samlRoleListScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "85f41d22-71a7-4626-8392-bdc0691c8797", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + } ] + }, { + "id" : "b8c8f09b-447c-48e1-83e9-8621f6847928", + "name" : "offline_access", + "description" : "OpenID Connect built-in scope: offline_access", + "protocol" : "openid-connect", + "attributes" : { + "consent.screen.text" : "${offlineAccessScopeConsentText}", + "display.on.consent.screen" : "true" + } + } ], + "defaultDefaultClientScopes" : [ "role_list", "profile", "email", "roles", "web-origins" ], + "defaultOptionalClientScopes" : [ "offline_access", "address", "phone", "microprofile-jwt" ], + "browserSecurityHeaders" : { + "contentSecurityPolicyReportOnly" : "", + "xContentTypeOptions" : "nosniff", + "xRobotsTag" : "none", + "xFrameOptions" : "SAMEORIGIN", + "xXSSProtection" : "1; mode=block", + "contentSecurityPolicy" : "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", + "strictTransportSecurity" : "max-age=31536000; includeSubDomains" + }, + "smtpServer" : { }, + "eventsEnabled" : false, + "eventsListeners" : [ "jboss-logging" ], + "enabledEventTypes" : [ ], + "adminEventsEnabled" : false, + "adminEventsDetailsEnabled" : false, + "components" : { + "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" : [ { + "id" : "96c46261-c336-4f03-a3e4-5d19ae7eaef4", + "name" : "Consent Required", + "providerId" : "consent-required", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "fbf457fe-4c8c-4f93-8423-fb5015c13645", + "name" : "Allowed Client Scopes", + "providerId" : "allowed-client-templates", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allow-default-scopes" : [ "true" ] + } + }, { + "id" : "db830636-c249-4adb-9a27-8e0ce5e79561", + "name" : "Allowed Client Scopes", + "providerId" : "allowed-client-templates", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allow-default-scopes" : [ "true" ] + } + }, { + "id" : "07f80809-471d-434f-81bb-7d987cd4c702", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "oidc-usermodel-attribute-mapper", "saml-role-list-mapper", "oidc-full-name-mapper", "oidc-address-mapper", "saml-user-property-mapper", "oidc-usermodel-property-mapper", "saml-user-attribute-mapper", "oidc-sha256-pairwise-sub-mapper" ] + } + }, { + "id" : "84e6d3ad-f704-45ea-9c66-fbeabb93718d", + "name" : "Max Clients Limit", + "providerId" : "max-clients", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "max-clients" : [ "200" ] + } + }, { + "id" : "721a22e7-46c2-4e1a-b2a8-06b5d413c96d", + "name" : "Trusted Hosts", + "providerId" : "trusted-hosts", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "host-sending-registration-request-must-match" : [ "true" ], + "client-uris-must-match" : [ "true" ] + } + }, { + "id" : "425b619f-acb1-47c8-94eb-13bfaacd6e0f", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "oidc-address-mapper", "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "oidc-usermodel-property-mapper", "oidc-full-name-mapper", "saml-user-property-mapper", "saml-role-list-mapper", "oidc-sha256-pairwise-sub-mapper" ] + } + }, { + "id" : "a8dc10a5-928c-4fde-bc67-14efbb193e2f", + "name" : "Full Scope Disabled", + "providerId" : "scope", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + } ], + "org.keycloak.keys.KeyProvider" : [ { + "id" : "7741edcb-6147-4464-bf20-5a1f5d71c08f", + "name" : "hmac-generated", + "providerId" : "hmac-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "4964aabf-5a0d-4d21-8432-36bf71c03369" ], + "secret" : [ "kQlcswpxNvUZEWTtY0BBjGgNPR8En95PheU17jnn0tpi9dell0cEOBoe9BK4yWoDvcygKB_lfWX1sC8fDZKf2A" ], + "priority" : [ "100" ], + "algorithm" : [ "HS256" ] + } + }, { + "id" : "5a8b3034-6bb3-46e0-aa0b-b080fc5cd973", + "name" : "aes-generated", + "providerId" : "aes-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "fa116fca-3046-4193-a1fa-728f518fef06" ], + "secret" : [ "ld__tKoNIQbhk-HunnzYgA" ], + "priority" : [ "100" ] + } + }, { + "id" : "31464a28-988a-4c0b-8703-4802407b265d", + "name" : "rsa-generated", + "providerId" : "rsa-generated", + "subComponents" : { }, + "config" : { + "privateKey" : [ "MIIEpAIBAAKCAQEAspkYHXC5zTd8SVt3zki3c25cJ/V/IqqCwRubJ9VweYX83A1g1vaTXil0B8LcUDV1VuqNted1Q3gGa16TzQTKEas4TnGd3PV/Zi2BaByzFFJkJcNauRY9Zqi5Qwyn+OnPjOZd/gEr6y56DDabyQ/5yiXjONboGQao9IBdlMhUcstwH4F9X2jWGn0m2LbxChOOP0C099FdhciA+RLNrNkp5Nm9s4Vh9uVV7Up9l9FeWlbf5dsyYKGl1YOY4dJpC4kHzZAsH3rie0PuNKWVpg2o6im5uv2Xj964ogfvwop6FzdjYvHmzKZ6JZ/NhA0Y5YWNpn9e6ea6XPpJTd1CL2H2dwIDAQABAoIBAAKGtdecw5QKh+CFwbESSD4Cvpz2FQFJhiXzHQO4OioN4iC+s7L2s+juDy0Y7YLY7rr3AGAlUPxOU1Dreo241p7fXCGH6+K3OkEYva7aURIlhDMgi0T48o9kLZKsOCgGLqBglc3E+HkQJDvN/fAfILpiRM+GAqxv8q3arvguyTsCbZk4nG3dycUSN44saoz/C5pewsy6GWy40bhgk7mnnBES8XHvbs4WN9fUehZGy1SPCZsn7LmK7F+p0AyauAndTV5Z1HjwWwZKw7n9IA2QzJtIC0H6yAURo7iozwJb2bYk7qTjufbix9ymwsWS9o0TNfcixYTLyAyrIh4Q8rRYCEECgYEA4xKhq8G7/1m/GQlrSHxGoQd4sFzWG2zpOu7xn7gW4dK3xuHXwjkSKOKCmnBbFUgFA/lkex/bnPGMFpM38MUWMH+Jtns6bDaUT14HAnU2MlB/vz+optxw9gfO4XYU5MkDThVrCpkrUHTJzRnE3C0vFyWQ8lRKb8FgUSBxe0FOU6ECgYEAyVmWu6re7Ju9mtHJ8ISFycE1VI6VCYimQzlFVACKkv9Z4ZadIEnU2i5RKV3l9mb/y0z5GJu6Ltao4gTuzBEOQStzULM2QREaNoSkFi0EJ1H1f07b+4Mx5DYbUnbAIH3NIlThexmXrUyxtTUOfDnsIVnKEQTR6LkZnUQMSgZzkxcCgYEA1zrmwO1uK5g+mRWjed5J+AIj9E7apr4xx6mKnxCXp87aYQnaP39m5hflIUvUGbTdBCpUgpvsxrLxTMiYIoA9CxUoTC47byzAoQYH8N121HQW0gkd66NQ8vLttij9numlV1LX1gDe3HEGgoClZujxFKiH3hnlQE5z5BGzXtfEzWECgYBZP12ht35yUCH90sl407TdlcdGwKBtBmXz3BnPvyGtQIQdiv4AhtlTED6nYFiDHGp7OZYcA0LGah2XeWpDh7fSySim95ivxJ3i1m5I6hEyQJDZqiG13RQrPJRlu/8zJ6/abNc5EkH57cnDMU5HYAE7UypO2t0UE5+35qav1SY7ZwKBgQC04iZxjds+kccvZEUAhgeWAw0Cada8EhIsrnSuEFrre8A+DXYD30ZS3qdYaGred02VBlHORErVr4GOVl7H1A23cNYNYFhv8oFW+nT7650yA7jS+9BzGXzXOF7scKom1gibRCFoQfOQ0RMCsar7a4XTF/LF5bwJ+dmwwcS+BghwbA==" ], + "certificate" : [ "MIICmzCCAYMCBgFvizUgGTANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjAwMTA5MTY0NjUyWhcNMzAwMTA5MTY0ODMyWjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCymRgdcLnNN3xJW3fOSLdzblwn9X8iqoLBG5sn1XB5hfzcDWDW9pNeKXQHwtxQNXVW6o2153VDeAZrXpPNBMoRqzhOcZ3c9X9mLYFoHLMUUmQlw1q5Fj1mqLlDDKf46c+M5l3+ASvrLnoMNpvJD/nKJeM41ugZBqj0gF2UyFRyy3AfgX1faNYafSbYtvEKE44/QLT30V2FyID5Es2s2Snk2b2zhWH25VXtSn2X0V5aVt/l2zJgoaXVg5jh0mkLiQfNkCwfeuJ7Q+40pZWmDajqKbm6/ZeP3riiB+/CinoXN2Ni8ebMpnoln82EDRjlhY2mf17p5rpc+klN3UIvYfZ3AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAKcy5+63542adcSf8nVOAVSntsA9ZredgYvnagfCkUipawbVws1rmhK/Yx7YstaRHRRAbQUIW4ZiaeTcitfhRoLSxt8kIO42ZMMg2PeRJizgoKI2Kn1dRhzF+Iwywl6zSCaRZIJr2vhNHtnuHkf5rTxd9KxwS6NrXbgMj3sSoGD/3aBdZ4L6PbDIvy8SXoFpyS3WrMACzt9N7F4Ac6yxbfF/66CxxNR1ij5+qHk4kvHeI6uNrm4rlEu31Y2p7wZPEW21iSdH1bgCHLzz2U/ctWl4MIhqQD/AX4K9zZtaopA1BW3DIKVXGRp6XMUdhg6lW7+sJ4Xem7QGdhLCRUR36f8=" ], + "priority" : [ "100" ] + } + } ] + }, + "internationalizationEnabled" : false, + "supportedLocales" : [ ], + "authenticationFlows" : [ { + "id" : "3aff9fdc-c99e-4566-ae19-31a38ba17e79", + "alias" : "Handle Existing Account", + "description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "idp-confirm-link", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "idp-email-verification", + "requirement" : "ALTERNATIVE", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "requirement" : "ALTERNATIVE", + "priority" : 30, + "flowAlias" : "Verify Existing Account by Re-authentication", + "userSetupAllowed" : false, + "autheticatorFlow" : true + } ] + }, { + "id" : "adf94ffa-8679-43ea-8905-de1dafacdfe1", + "alias" : "Verify Existing Account by Re-authentication", + "description" : "Reauthentication of existing account", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "idp-username-password-form", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "auth-otp-form", + "requirement" : "OPTIONAL", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "5e53994c-1968-42f9-8309-a7f5f08b80fe", + "alias" : "browser", + "description" : "browser based authentication", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "auth-cookie", + "requirement" : "ALTERNATIVE", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "auth-spnego", + "requirement" : "DISABLED", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "identity-provider-redirector", + "requirement" : "ALTERNATIVE", + "priority" : 25, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "requirement" : "ALTERNATIVE", + "priority" : 30, + "flowAlias" : "forms", + "userSetupAllowed" : false, + "autheticatorFlow" : true + } ] + }, { + "id" : "7d1243c3-bf19-4510-a2e5-e43a1972716d", + "alias" : "clients", + "description" : "Base authentication for clients", + "providerId" : "client-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "client-secret", + "requirement" : "ALTERNATIVE", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "client-jwt", + "requirement" : "ALTERNATIVE", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "client-secret-jwt", + "requirement" : "ALTERNATIVE", + "priority" : 30, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "client-x509", + "requirement" : "ALTERNATIVE", + "priority" : 40, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "9781461a-c351-4cf2-bb58-4f1dcc0688c5", + "alias" : "direct grant", + "description" : "OpenID Connect Resource Owner Grant", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "direct-grant-validate-username", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "direct-grant-validate-password", + "requirement" : "REQUIRED", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "direct-grant-validate-otp", + "requirement" : "OPTIONAL", + "priority" : 30, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "d688ad76-10ea-473f-95cd-1ab5fd07f244", + "alias" : "docker auth", + "description" : "Used by Docker clients to authenticate against the IDP", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "docker-http-basic-authenticator", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "814f20fe-5169-4c61-9600-af5f4b686937", + "alias" : "first broker login", + "description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticatorConfig" : "review profile config", + "authenticator" : "idp-review-profile", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticatorConfig" : "create unique user config", + "authenticator" : "idp-create-user-if-unique", + "requirement" : "ALTERNATIVE", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "requirement" : "ALTERNATIVE", + "priority" : 30, + "flowAlias" : "Handle Existing Account", + "userSetupAllowed" : false, + "autheticatorFlow" : true + } ] + }, { + "id" : "139e36e2-48f2-4a1b-8973-5bd8ec3b4a72", + "alias" : "forms", + "description" : "Username, password, otp and other auth forms.", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "auth-username-password-form", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "auth-otp-form", + "requirement" : "OPTIONAL", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "05295d71-477c-4538-b7ed-9f80523200e5", + "alias" : "http challenge", + "description" : "An authentication flow based on challenge-response HTTP Authentication Schemes", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "no-cookie-redirect", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "basic-auth", + "requirement" : "REQUIRED", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "basic-auth-otp", + "requirement" : "DISABLED", + "priority" : 30, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "auth-spnego", + "requirement" : "DISABLED", + "priority" : 40, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "654212ae-a969-4cfe-9ae2-4cb0f41ffba6", + "alias" : "registration", + "description" : "registration flow", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "registration-page-form", + "requirement" : "REQUIRED", + "priority" : 10, + "flowAlias" : "registration form", + "userSetupAllowed" : false, + "autheticatorFlow" : true + } ] + }, { + "id" : "98e70802-b4f4-49c2-9558-6a79937261cc", + "alias" : "registration form", + "description" : "registration form", + "providerId" : "form-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "registration-user-creation", + "requirement" : "REQUIRED", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "registration-profile-action", + "requirement" : "REQUIRED", + "priority" : 40, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "registration-password-action", + "requirement" : "REQUIRED", + "priority" : 50, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "registration-recaptcha-action", + "requirement" : "DISABLED", + "priority" : 60, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "83abd3e6-f38c-4e10-826c-ab90727e1737", + "alias" : "reset credentials", + "description" : "Reset credentials for a user if they forgot their password or something", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "reset-credentials-choose-user", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "reset-credential-email", + "requirement" : "REQUIRED", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "reset-password", + "requirement" : "REQUIRED", + "priority" : 30, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "reset-otp", + "requirement" : "OPTIONAL", + "priority" : 40, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "95484597-92f3-4476-ae49-a921c82e5348", + "alias" : "saml ecp", + "description" : "SAML ECP Profile Authentication Flow", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "http-basic-authenticator", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + } ], + "authenticatorConfig" : [ { + "id" : "d9b188e1-d85c-4333-b366-55502236b859", + "alias" : "create unique user config", + "config" : { + "require.password.update.after.registration" : "false" + } + }, { + "id" : "bce759c3-eb1f-48d3-90b3-c6f7c2cca7d4", + "alias" : "review profile config", + "config" : { + "update.profile.on.first.login" : "missing" + } + } ], + "requiredActions" : [ { + "alias" : "CONFIGURE_TOTP", + "name" : "Configure OTP", + "providerId" : "CONFIGURE_TOTP", + "enabled" : true, + "defaultAction" : false, + "priority" : 10, + "config" : { } + }, { + "alias" : "terms_and_conditions", + "name" : "Terms and Conditions", + "providerId" : "terms_and_conditions", + "enabled" : false, + "defaultAction" : false, + "priority" : 20, + "config" : { } + }, { + "alias" : "UPDATE_PASSWORD", + "name" : "Update Password", + "providerId" : "UPDATE_PASSWORD", + "enabled" : true, + "defaultAction" : false, + "priority" : 30, + "config" : { } + }, { + "alias" : "UPDATE_PROFILE", + "name" : "Update Profile", + "providerId" : "UPDATE_PROFILE", + "enabled" : true, + "defaultAction" : false, + "priority" : 40, + "config" : { } + }, { + "alias" : "VERIFY_EMAIL", + "name" : "Verify Email", + "providerId" : "VERIFY_EMAIL", + "enabled" : true, + "defaultAction" : false, + "priority" : 50, + "config" : { } + } ], + "browserFlow" : "browser", + "registrationFlow" : "registration", + "directGrantFlow" : "direct grant", + "resetCredentialsFlow" : "reset credentials", + "clientAuthenticationFlow" : "clients", + "dockerAuthenticationFlow" : "docker auth", + "attributes" : { + "_browser_header.xXSSProtection" : "1; mode=block", + "_browser_header.strictTransportSecurity" : "max-age=31536000; includeSubDomains", + "_browser_header.xFrameOptions" : "SAMEORIGIN", + "quickLoginCheckMilliSeconds" : "1000", + "permanentLockout" : "false", + "displayName" : "Keycloak", + "_browser_header.xRobotsTag" : "none", + "maxFailureWaitSeconds" : "900", + "displayNameHtml" : "
Keycloak
", + "minimumQuickLoginWaitSeconds" : "60", + "failureFactor" : "30", + "maxDeltaTimeSeconds" : "43200", + "_browser_header.xContentTypeOptions" : "nosniff", + "offlineSessionMaxLifespan" : "5184000", + "_browser_header.contentSecurityPolicyReportOnly" : "", + "bruteForceProtected" : "false", + "_browser_header.contentSecurityPolicy" : "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", + "offlineSessionMaxLifespanEnabled" : "false", + "waitIncrementSeconds" : "60" + }, + "keycloakVersion" : "6.0.1", + "userManagedAccessAllowed" : false +} \ No newline at end of file diff --git a/docker-images/nginx/.gitignore b/docker-images/nginx/.gitignore new file mode 100644 index 0000000..9b5e042 --- /dev/null +++ b/docker-images/nginx/.gitignore @@ -0,0 +1,2 @@ +conf.d/servers.conf +conf.d/common/server-revproxy.conf.inc diff --git a/docker-images/web/nginx.Dockerfile b/docker-images/nginx/Dockerfile similarity index 71% rename from docker-images/web/nginx.Dockerfile rename to docker-images/nginx/Dockerfile index 319c550..fefde42 100644 --- a/docker-images/web/nginx.Dockerfile +++ b/docker-images/nginx/Dockerfile @@ -4,7 +4,7 @@ FROM nginx:1.15.10 ENV HTTP_SCHEME="http" \ ALL_TIMEOUTS_SECONDS="600" -COPY nginx.docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh +COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh RUN chmod a+x /usr/local/bin/docker-entrypoint.sh CMD docker-entrypoint.sh diff --git a/docker-images/nginx/conf.d/common/cors.inc b/docker-images/nginx/conf.d/common/cors.inc new file mode 100644 index 0000000..4935717 --- /dev/null +++ b/docker-images/nginx/conf.d/common/cors.inc @@ -0,0 +1,8 @@ +add_header 'Access-Control-Allow-Origin' "$http_origin" always; +add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, HEAD, DELETE, OPTIONS' always; +add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always; +add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always; + +if ($request_method = OPTIONS) { +return 200; +} diff --git a/docker-images/nginx/conf.d/common/server-default.conf.inc b/docker-images/nginx/conf.d/common/server-default.conf.inc new file mode 100644 index 0000000..b353303 --- /dev/null +++ b/docker-images/nginx/conf.d/common/server-default.conf.inc @@ -0,0 +1,7 @@ +# --- web root configuration --- +location / { + root /www-data/; + + # redirect root to glowing-bear + rewrite ^(/)$ /glowing-bear; +} diff --git a/docker-images/web/nginx-conf.d/common/server-https.conf.inc b/docker-images/nginx/conf.d/common/server-https.conf.inc similarity index 100% rename from docker-images/web/nginx-conf.d/common/server-https.conf.inc rename to docker-images/nginx/conf.d/common/server-https.conf.inc diff --git a/docker-images/web/nginx-conf.d/common/server-revproxy.conf.inc.template b/docker-images/nginx/conf.d/common/server-revproxy.conf.inc.template similarity index 65% rename from docker-images/web/nginx-conf.d/common/server-revproxy.conf.inc.template rename to docker-images/nginx/conf.d/common/server-revproxy.conf.inc.template index db4c279..6621f56 100644 --- a/docker-images/web/nginx-conf.d/common/server-revproxy.conf.inc.template +++ b/docker-images/nginx/conf.d/common/server-revproxy.conf.inc.template @@ -38,21 +38,6 @@ location /pgadmin { proxy_redirect http://$upstream_host/pgadmin /pgadmin; } -location /pic-sure-api-2 { - - add_header 'Access-Control-Allow-Origin' "$http_origin"; - add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, HEAD, DELETE, OPTIONS'; - add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; - add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; - - if ($request_method = OPTIONS) { - return 200; - } - - set $upstream_host picsure; - proxy_pass http://$upstream_host:8080; -} - location /i2b2 { set $upstream_host i2b2; proxy_pass http://$upstream_host:8080; @@ -63,7 +48,32 @@ location /glowing-bear { proxy_pass http://$upstream_host; } -location /medco-connector { +location /medco { + include /etc/nginx/conf.d/common/cors.inc; set $upstream_host medco-connector; proxy_pass http://$upstream_host:1999; } + + +### --- only used in dev or test profiles + +location /local-3nodes/medco-0 { + include /etc/nginx/conf.d/common/cors.inc; + set $upstream_host medco-connector-srv0; + rewrite /local-3nodes/medco-0/(.*) /medco/$1 break; + proxy_pass http://$upstream_host:1999; +} + +location /local-3nodes/medco-1 { + include /etc/nginx/conf.d/common/cors.inc; + set $upstream_host medco-connector-srv1; + rewrite /local-3nodes/medco-1/(.*) /medco/$1 break; + proxy_pass http://$upstream_host:1999; +} + +location /local-3nodes/medco-2 { + include /etc/nginx/conf.d/common/cors.inc; + set $upstream_host medco-connector-srv2; + rewrite /local-3nodes/medco-2/(.*) /medco/$1 break; + proxy_pass http://$upstream_host:1999; +} diff --git a/docker-images/web/nginx-conf.d/servers.conf.http.inc b/docker-images/nginx/conf.d/servers.conf.http.inc similarity index 100% rename from docker-images/web/nginx-conf.d/servers.conf.http.inc rename to docker-images/nginx/conf.d/servers.conf.http.inc diff --git a/docker-images/web/nginx-conf.d/servers.conf.https.inc b/docker-images/nginx/conf.d/servers.conf.https.inc similarity index 100% rename from docker-images/web/nginx-conf.d/servers.conf.https.inc rename to docker-images/nginx/conf.d/servers.conf.https.inc diff --git a/docker-images/web/nginx-conf.d/servers.conf.template b/docker-images/nginx/conf.d/servers.conf.template similarity index 100% rename from docker-images/web/nginx-conf.d/servers.conf.template rename to docker-images/nginx/conf.d/servers.conf.template diff --git a/docker-images/web/nginx.docker-entrypoint.sh b/docker-images/nginx/docker-entrypoint.sh similarity index 100% rename from docker-images/web/nginx.docker-entrypoint.sh rename to docker-images/nginx/docker-entrypoint.sh diff --git a/docker-images/web/www-data/conf.env b/docker-images/nginx/www-data/conf.env similarity index 100% rename from docker-images/web/www-data/conf.env rename to docker-images/nginx/www-data/conf.env diff --git a/docker-images/nginx/www-data/index.html b/docker-images/nginx/www-data/index.html new file mode 100644 index 0000000..7362b2c --- /dev/null +++ b/docker-images/nginx/www-data/index.html @@ -0,0 +1,29 @@ +MedCo Node Instance + +
+

MedCo Node Instance

+ +

Glowing Bear

+ +
+
+ +

Administration

+
+

PgAdmin

+

Keycloak

+

I2b2 MedCo Axis2 Management

+ +
+
+ + + diff --git a/docker-images/picsure/Dockerfile b/docker-images/picsure/Dockerfile deleted file mode 100644 index 11567d2..0000000 --- a/docker-images/picsure/Dockerfile +++ /dev/null @@ -1,66 +0,0 @@ -FROM maven:3.6 AS build - -ENV GIT_REPO="https://github.com/hms-dbmi/pic-sure.git" \ - VERSION=61331e1bf8c085ce608627e9b94a835c9655fc7a - -# get dependencies and sources -WORKDIR /src -COPY patches /patches -RUN apt-get update && \ - apt-get install -y git && \ - git clone $GIT_REPO . && \ - git checkout ${VERSION} && \ - git apply /patches/*.diff - -# build -RUN mvn -pl '!pic-sure-api-wildfly' package - -# ------------------------------------------- -FROM jboss/wildfly:16.0.0.Final as release - -COPY --from=build --chown=jboss:jboss /src/pic-sure-api-war/src/main/resources/wildfly-configuration/standalone.xml wildfly/standalone/configuration/ -COPY --from=build --chown=jboss:jboss /src/pic-sure-api-war/target/pic-sure-api-war.war wildfly/standalone/deployments/pic-sure-api-2.war - -# pre-requisites -USER root -COPY docker-entrypoint.sh /usr/local/bin/ -COPY sql/* /sql/ -RUN yum update -y && yum -y install postgresql wget && yum clean all && \ - mkdir /modules && chmod -R a+w /modules && \ - chmod a+x /usr/local/bin/docker-entrypoint.sh -USER jboss - -# trust store variables -ENV TRUSTSTORE_PATH="/medco-configuration/truststore" \ - TRUSTSTORE_PASSWORD="truststore" - -# set up postgresql database and CORS configuration -COPY conf/postgresql.cli conf/jwks.cli conf/truststore.cli / -RUN wget https://jdbc.postgresql.org/download/postgresql-42.2.5.jar -O /modules/postgresql-jdbc.jar && \ - /opt/jboss/wildfly/bin/jboss-cli.sh --file=/truststore.cli && \ - /opt/jboss/wildfly/bin/jboss-cli.sh --file=/postgresql.cli && \ - /opt/jboss/wildfly/bin/jboss-cli.sh --file=/jwks.cli && \ - rm -rf /opt/jboss/wildfly/standalone/configuration/standalone_xml_history/current - -# run-time variables used directly by PIC-SURE -ENV PICSURE2_PGDB_ADDRESS="postgresql" \ - PICSURE2_PGDB_PORT="5432" \ - PICSURE2_PGDB_DB="picsure" \ - PICSURE2_PGDB_USER="picsure" \ - PICSURE2_PGDB_PW="picsure" \ - VERIFY_USER_METHOD="local_jwks" \ - TOKEN_INTROSPECTION_URL="http://keycloak:8080/auth/realms/master/protocol/openid-connect/token/introspect" \ - TOKEN_INTROSPECTION_TOKEN="none" \ - PICSURE2_USER_ID_CLAIM="email" \ - PICSURE2_CLIENT_SECRET="none" \ - PICSURE_2_TOKEN="none" \ - PICSURE2_JWKS_URL="http://keycloak:8080/auth/realms/master/protocol/openid-connect/certs" \ - HTTP_CLIENT_TIMEOUT_SECONDS="600" - -# additional run-time variables -ENV PICSURE2_CLIENT_ID="picsure" \ - MEDCO_NETWORK_NAME="testnetwork" \ - MEDCO_NODES_NAME="a,b,c" \ - MEDCO_NODES_CONNECTOR_URL="http://medco-connector-srv0/picsure2,http://medco-connector-srv1/picsure2,http://medco-connector-srv2/picsure2" - -ENTRYPOINT ["docker-entrypoint.sh"] diff --git a/docker-images/picsure/README.md b/docker-images/picsure/README.md deleted file mode 100644 index 053c4e7..0000000 --- a/docker-images/picsure/README.md +++ /dev/null @@ -1,6 +0,0 @@ -This docker image sets up PIC-SURE with a PostgreSQL database, and allows to rely on Keycloak for the authentication by enabling OAuth2 client authentication. - -PICSURE_2_TOKEN: token to talk server-to-PICSURE2 / intra-picsure requests (e.g. aggregate to query) -(should be valid to be used, but not used here) - -in query to resource, the BEARER_TOKEN key in resource credentials will have the value configured in DB \ No newline at end of file diff --git a/docker-images/picsure/conf/jwks.cli b/docker-images/picsure/conf/jwks.cli deleted file mode 100644 index d3e4311..0000000 --- a/docker-images/picsure/conf/jwks.cli +++ /dev/null @@ -1,3 +0,0 @@ -embed-server -/subsystem=naming/binding=java\:global\/jwks_url:add(binding-type=simple, value=${env.PICSURE2_JWKS_URL}) -stop-embedded-server diff --git a/docker-images/picsure/conf/postgresql.cli b/docker-images/picsure/conf/postgresql.cli deleted file mode 100644 index ff08e86..0000000 --- a/docker-images/picsure/conf/postgresql.cli +++ /dev/null @@ -1,7 +0,0 @@ -embed-server -data-source remove --name=PicsureDS -/subsystem=datasources/jdbc-driver=mysql:remove -module add --name=org.postgresql --resources=/modules/postgresql-jdbc.jar --dependencies=javax.api,javax.transaction.api -/subsystem=datasources/jdbc-driver=postgres:add(driver-name="postgres",driver-module-name="org.postgresql",driver-class-name=org.postgresql.Driver) -data-source add --jndi-name=java:jboss/datasources/PicsureDS --name=PicsureDS --connection-url=jdbc:postgresql://${env.PICSURE2_PGDB_ADDRESS}:${env.PICSURE2_PGDB_PORT}/${env.PICSURE2_PGDB_DB} --driver-name=postgres --user-name=${env.PICSURE2_PGDB_USER} --password=${env.PICSURE2_PGDB_PW} -stop-embedded-server diff --git a/docker-images/picsure/conf/truststore.cli b/docker-images/picsure/conf/truststore.cli deleted file mode 100644 index c6cc1f5..0000000 --- a/docker-images/picsure/conf/truststore.cli +++ /dev/null @@ -1,4 +0,0 @@ -embed-server -/system-property=javax.net.ssl.trustStore:add(value="${env.TRUSTSTORE_PATH}") -/system-property=javax.net.ssl.trustStorePassword:add(value="${env.TRUSTSTORE_PASSWORD}") -stop-embedded-server diff --git a/docker-images/picsure/docker-entrypoint.sh b/docker-images/picsure/docker-entrypoint.sh deleted file mode 100644 index 7094b33..0000000 --- a/docker-images/picsure/docker-entrypoint.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env bash -set -Eeuo pipefail - -# wait for postgres to be available -export PGPASSWORD="${PICSURE2_PGDB_PW}" -PSQL_PARAMS="-v ON_ERROR_STOP=1 -h ${PICSURE2_PGDB_ADDRESS} -p ${PICSURE2_PGDB_PORT} -U ${PICSURE2_PGDB_USER}" -until psql ${PSQL_PARAMS} -d postgres -c '\q'; do - >&2 echo "Waiting for postgresql..." - sleep 1 -done - -# load initial data if database does not exist (credentials must be valid and have create database right) -DB_CHECK=`psql ${PSQL_PARAMS} -d postgres -X -A -t -c "select count(*) from pg_database where datname = '${PICSURE2_PGDB_DB}';"` -if [[ "$DB_CHECK" -ne "1" ]]; then -echo "Initialising PIC-SURE database" - psql ${PSQL_PARAMS} -d postgres <<-EOSQL - CREATE DATABASE ${PICSURE2_PGDB_DB}; - ALTER DATABASE ${PICSURE2_PGDB_DB} OWNER TO ${PICSURE2_PGDB_USER}; -EOSQL - - psql ${PSQL_PARAMS} -d ${PICSURE2_PGDB_DB} <<-EOSQL - grant all on schema public to ${PICSURE2_PGDB_DB}; - grant all privileges on all tables in schema public to ${PICSURE2_PGDB_USER}; -EOSQL - - psql ${PSQL_PARAMS} -d ${PICSURE2_PGDB_DB} -f "/sql/picsure2_db_ddl.sql" - psql ${PSQL_PARAMS} -d ${PICSURE2_PGDB_DB} -f "/sql/medco_resource_function.sql" -fi - -# register in the database the medco resources -for (( IDX=0; ; IDX++ )); do - MEDCO_NODE_NAME=$(echo "${MEDCO_NODES_NAME}" | cut -f$(($IDX+1)) -d,) - MEDCO_NODE_CONNECTOR_URL=$(echo "${MEDCO_NODES_CONNECTOR_URL}" | cut -f$(($IDX+1)) -d,) - - if [[ -z ${MEDCO_NODE_NAME} ]]; then - break - fi - - UUID=$(uuidgen) - DESC="MedCo node ${IDX} (${MEDCO_NODE_NAME}) from network ${MEDCO_NETWORK_NAME}" - NAME="MEDCO_${MEDCO_NETWORK_NAME}_${IDX}_${MEDCO_NODE_NAME}" - RSPATH="${MEDCO_NODE_CONNECTOR_URL}" - TARGETURL="" - TOKEN="" - echo "select add_or_update_medco_resource('${UUID}', '${DESC}', '${NAME}', '${RSPATH}', '${TARGETURL}', '${TOKEN}');" - psql ${PSQL_PARAMS} -d ${PICSURE2_PGDB_DB} <<-EOSQL - select add_or_update_medco_resource('${UUID}', '${DESC}', '${NAME}', '${RSPATH}', '${TARGETURL}', '${TOKEN}'); -EOSQL -done - -exec /opt/jboss/wildfly/bin/standalone.sh -b 0.0.0.0 -bmanagement 0.0.0.0 diff --git a/docker-images/picsure/patches/http-req-timeouts.diff b/docker-images/picsure/patches/http-req-timeouts.diff deleted file mode 100644 index 5bd3b20..0000000 --- a/docker-images/picsure/patches/http-req-timeouts.diff +++ /dev/null @@ -1,78 +0,0 @@ -diff --git a/pic-sure-util/src/main/java/edu/harvard/dbmi/avillach/util/HttpClientUtil.java b/pic-sure-util/src/main/java/edu/harvard/dbmi/avillach/util/HttpClientUtil.java -index c1ea7e0..674f2c8 100644 ---- a/pic-sure-util/src/main/java/edu/harvard/dbmi/avillach/util/HttpClientUtil.java -+++ b/pic-sure-util/src/main/java/edu/harvard/dbmi/avillach/util/HttpClientUtil.java -@@ -8,6 +8,7 @@ import edu.harvard.dbmi.avillach.util.exception.ResourceInterfaceException; - import org.apache.commons.io.IOUtils; - import org.apache.http.Header; - import org.apache.http.HttpResponse; -+import org.apache.http.client.config.RequestConfig; - import org.apache.http.client.methods.HttpGet; - import org.apache.http.client.methods.HttpPost; - import org.apache.http.entity.StringEntity; -@@ -34,10 +35,29 @@ import java.util.function.Predicate; - import java.util.stream.Collectors; - - public class HttpClientUtil { -+ -+ private static String HTTP_CLIENT_TIMEOUT_SECONDS = System.getenv("HTTP_CLIENT_TIMEOUT_SECONDS"); -+ - private final static ObjectMapper json = new ObjectMapper(); - - private final static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class); - -+ /** -+ * @return new requestconfig for the HTTP client with timeouts set -+ */ -+ private static RequestConfig getNewRequestConfig() { -+ int timeout = 600; -+ try { -+ timeout = Integer.parseInt(HTTP_CLIENT_TIMEOUT_SECONDS); -+ } catch (NumberFormatException e) { -+ logger.error("error parsing HTTP_CLIENT_TIMEOUT_SECONDS, defaulted to 600s"); -+ } -+ -+ return RequestConfig.custom() -+ .setConnectTimeout(timeout * 1000) -+ .setConnectionRequestTimeout(timeout * 1000) -+ .setSocketTimeout(timeout * 1000).build(); -+ } - - public static HttpResponse retrieveGetResponse(String uri, List
headers) { - return retrieveGetResponse(uri, headers.toArray(new Header[headers.size()])); -@@ -53,7 +73,7 @@ public class HttpClientUtil { - try { - logger.debug("HttpClientUtil retrieveGetResponse()"); - -- HttpClient client = HttpClientBuilder.create().build(); -+ HttpClient client = HttpClientBuilder.create().setDefaultRequestConfig(getNewRequestConfig()).build(); - return simpleGet(client, uri, headers); - } catch (ApplicationException e) { - //TODO: Write custom exception -@@ -100,7 +120,7 @@ public class HttpClientUtil { - headerList = new ArrayList<>(Arrays.asList(headers)); - headerList.add(new BasicHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)); - -- HttpClient client = HttpClientBuilder.create().build(); -+ HttpClient client = HttpClientBuilder.create().setDefaultRequestConfig(getNewRequestConfig()).build(); - return simplePost(uri, client, new StringEntity(body), headerList.toArray(new Header[headerList.size()])); - } catch (ApplicationException | UnsupportedEncodingException e) { - //TODO: Write custom exception -@@ -168,7 +188,7 @@ public class HttpClientUtil { - throws ApplicationException{ - - if (client == null) -- client = HttpClientBuilder.create().build(); -+ client = HttpClientBuilder.create().setDefaultRequestConfig(getNewRequestConfig()).build(); - - HttpPost post = new HttpPost(uri); - post.setHeaders(headers); -@@ -235,7 +255,7 @@ public class HttpClientUtil { - throws ApplicationException{ - - if (client == null) -- client = HttpClientBuilder.create().build(); -+ client = HttpClientBuilder.create().setDefaultRequestConfig(getNewRequestConfig()).build(); - - HttpGet get = new HttpGet(uri); - get.setHeaders(headers); diff --git a/docker-images/picsure/patches/jwks-support.diff b/docker-images/picsure/patches/jwks-support.diff deleted file mode 100644 index 8b0784c..0000000 --- a/docker-images/picsure/patches/jwks-support.diff +++ /dev/null @@ -1,150 +0,0 @@ -diff --git a/pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/security/JWKSKeyResolver.java b/pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/security/JWKSKeyResolver.java -new file mode 100644 -index 0000000..ad5f15f ---- /dev/null -+++ b/pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/security/JWKSKeyResolver.java -@@ -0,0 +1,105 @@ -+package edu.harvard.dbmi.avillach.security; -+ -+import com.fasterxml.jackson.databind.JsonNode; -+import com.fasterxml.jackson.databind.ObjectMapper; -+import edu.harvard.dbmi.avillach.PicSureWarInit; -+import io.jsonwebtoken.Claims; -+import io.jsonwebtoken.JwsHeader; -+import io.jsonwebtoken.SigningKeyResolverAdapter; -+import io.jsonwebtoken.impl.Base64UrlCodec; -+import io.jsonwebtoken.impl.DefaultClaims; -+import org.apache.http.client.methods.CloseableHttpResponse; -+import org.apache.http.client.methods.HttpGet; -+import org.apache.http.impl.client.CloseableHttpClient; -+import org.apache.http.util.EntityUtils; -+import org.slf4j.Logger; -+import org.slf4j.LoggerFactory; -+ -+import javax.annotation.Resource; -+import java.math.BigInteger; -+import java.security.Key; -+import java.security.KeyFactory; -+import java.security.PublicKey; -+import java.security.spec.RSAPublicKeySpec; -+import java.util.HashMap; -+import java.util.Map; -+ -+import static edu.harvard.dbmi.avillach.util.Utilities.applyProxySettings; -+import static edu.harvard.dbmi.avillach.util.Utilities.buildHttpClientContext; -+ -+public class JWKSKeyResolver extends SigningKeyResolverAdapter { -+ -+ private Logger logger = LoggerFactory.getLogger(JWKSKeyResolver.class); -+ -+ private String jwksUrl; -+ -+ /** -+ * Resolved keys cache. -+ * Key ID -> Public Key -+ */ -+ private Map keyCache = new HashMap<>(); -+ -+ private static JWKSKeyResolver instance = new JWKSKeyResolver(); -+ -+ static JWKSKeyResolver getInstance(String jwksUrl) { -+ instance.jwksUrl = jwksUrl; -+ return instance; -+ } -+ -+ @Override -+ public Key resolveSigningKey(JwsHeader header, String plaintext) { -+ return resolveSigningKey(header, new DefaultClaims()); -+ } -+ -+ @Override -+ public Key resolveSigningKey(JwsHeader jwsHeader, Claims claims) { -+ String kid = jwsHeader.getKeyId(); -+ -+ if (keyCache.containsKey(kid)) { -+ return keyCache.get(kid); -+ } -+ -+ ObjectMapper json = PicSureWarInit.objectMapper; -+ CloseableHttpClient client = PicSureWarInit.CLOSEABLE_HTTP_CLIENT; -+ CloseableHttpResponse response = null; -+ HttpGet get = new HttpGet(jwksUrl); -+ applyProxySettings(get); -+ -+ try { -+ response = client.execute(get, buildHttpClientContext()); -+ if (response.getStatusLine().getStatusCode() != 200) { -+ logger.error("resolveSigningKey() error back from server [" -+ + jwksUrl + "]: " + EntityUtils.toString(response.getEntity())); -+ return null; -+ } -+ -+ JsonNode responseContent = json.readTree(response.getEntity().getContent()); -+ for (final JsonNode keyObj : responseContent.get("keys")) { -+ if (keyObj.get("kid").asText().equals(kid)) { -+ Base64UrlCodec b64Codec = new Base64UrlCodec(); -+ BigInteger n = new BigInteger(1, b64Codec.decode(keyObj.get("n").asText())); -+ BigInteger e = new BigInteger(1, b64Codec.decode(keyObj.get("e").asText())); -+ -+ KeyFactory kf = KeyFactory.getInstance("RSA"); -+ PublicKey key = kf.generatePublic(new RSAPublicKeySpec(n, e)); -+ -+ keyCache.put(kid, key); -+ return key; -+ } -+ } -+ -+ logger.error("resolveSigningKey() key ID not found"); -+ -+ } catch (Exception ex) { -+ logger.error("resolveSigningKey() Exception when retrieving JWKS url: " + ex.getMessage()); -+ } finally { -+ try { -+ if (response != null) -+ response.close(); -+ } catch (Exception ex) { -+ logger.error("resolveSigningKey() Exception when closing http response: " + ex.getMessage()); -+ } -+ } -+ return null; -+ } -+} -diff --git a/pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/security/JWTFilter.java b/pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/security/JWTFilter.java -index e894851..e02f953 100755 ---- a/pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/security/JWTFilter.java -+++ b/pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/security/JWTFilter.java -@@ -55,6 +55,8 @@ public class JWTFilter implements ContainerRequestFilter { - private String clientSecret; - @Resource(mappedName = "java:global/user_id_claim") - private String userIdClaim; -+ @Resource(mappedName = "java:global/jwks_url") -+ private String jwksUrl; - - @Inject - PicSureWarInit picSureWarInit; -@@ -79,8 +81,10 @@ public class JWTFilter implements ContainerRequestFilter { - - if (PicSureWarInit.VERIFY_METHOD_TOKEN_INTRO.equalsIgnoreCase(picSureWarInit.getVerify_user_method())) { - authenticatedUser = callTokenIntroEndpoint(requestContext, token, userIdClaim); -- } else { -+ } else if (PicSureWarInit.VERIFY_METHOD_LOCAL.equalsIgnoreCase(picSureWarInit.getVerify_user_method())) { - authenticatedUser = callLocalAuthentication(requestContext, token); -+ } else { -+ authenticatedUser = callLocalJwksAuthentication(requestContext, token); - } - - if (authenticatedUser == null) { -@@ -246,4 +250,13 @@ public class JWTFilter implements ContainerRequestFilter { - - return userRepo.findOrCreate(new User().setSubject(subject).setUserId(userId)); - } -+ -+ private User callLocalJwksAuthentication(ContainerRequestContext requestContext, String token) throws JwtException{ -+ Jws jws = Jwts.parser().setSigningKeyResolver(JWKSKeyResolver.getInstance(jwksUrl)).parseClaimsJws(token); -+ -+ String subject = jws.getBody().getSubject(); -+ String userId = jws.getBody().get(userIdClaim, String.class); -+ -+ return userRepo.findOrCreate(new User().setSubject(subject).setUserId(userId)); -+ } - } diff --git a/docker-images/picsure/patches/postgresql-support.diff b/docker-images/picsure/patches/postgresql-support.diff deleted file mode 100644 index 4f0612d..0000000 --- a/docker-images/picsure/patches/postgresql-support.diff +++ /dev/null @@ -1,72 +0,0 @@ -diff --git a/pic-sure-api-data/pom.xml b/pic-sure-api-data/pom.xml -index 3728c5e..14b4e31 100755 ---- a/pic-sure-api-data/pom.xml -+++ b/pic-sure-api-data/pom.xml -@@ -37,5 +37,12 @@ - org.hibernate - hibernate-core - -+ -+ -+ org.hibernate -+ hibernate-core -+ 5.2.13.Final -+ provided -+ - - -diff --git a/pic-sure-api-data/src/main/java/edu/harvard/dbmi/avillach/data/HibernatePrefixNamingStrategy.java b/pic-sure-api-data/src/main/java/edu/harvard/dbmi/avillach/data/HibernatePrefixNamingStrategy.java -new file mode 100644 -index 0000000..3db5f9c ---- /dev/null -+++ b/pic-sure-api-data/src/main/java/edu/harvard/dbmi/avillach/data/HibernatePrefixNamingStrategy.java -@@ -0,0 +1,21 @@ -+package edu.harvard.dbmi.avillach.data; -+ -+import org.hibernate.boot.model.naming.Identifier; -+import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl; -+import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; -+ -+ -+/** -+ * Physical naming strategy that adds a prefix to the tables. -+ */ -+public class HibernatePrefixNamingStrategy extends PhysicalNamingStrategyStandardImpl { -+ private static final String TABLE_PREFIX = "PICSURE_"; -+ -+ @Override -+ public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironment) { -+ return jdbcEnvironment.getIdentifierHelper().toIdentifier( -+ TABLE_PREFIX + name.getText(), -+ name.isQuoted() -+ ); -+ } -+} -diff --git a/pic-sure-api-data/src/main/java/edu/harvard/dbmi/avillach/data/entity/BaseEntity.java b/pic-sure-api-data/src/main/java/edu/harvard/dbmi/avillach/data/entity/BaseEntity.java -index 93cdafe..b4f79b0 100644 ---- a/pic-sure-api-data/src/main/java/edu/harvard/dbmi/avillach/data/entity/BaseEntity.java -+++ b/pic-sure-api-data/src/main/java/edu/harvard/dbmi/avillach/data/entity/BaseEntity.java -@@ -14,7 +14,7 @@ public abstract class BaseEntity { - @GenericGenerator( - name = "UUID", - strategy = "org.hibernate.id.UUIDGenerator") -- @Column(columnDefinition = "BINARY(16)") -+ @Column(columnDefinition = "uuid") - protected UUID uuid; - - public UUID getUuid() { -diff --git a/pic-sure-api-war/src/main/resources/META-INF/persistence.xml b/pic-sure-api-war/src/main/resources/META-INF/persistence.xml -index 12c75db..ae070f0 100644 ---- a/pic-sure-api-war/src/main/resources/META-INF/persistence.xml -+++ b/pic-sure-api-war/src/main/resources/META-INF/persistence.xml -@@ -11,8 +11,8 @@ - - - -- -- -+ -+ -