diff --git a/.circleci/config.yml b/.circleci/config.yml index a0658a7878e..31e8987335e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -43,8 +43,7 @@ jobs: export FRONTEND_ORG=$(grep 'frontend\.groupId' pom.xml | sed 's///g' | sed 's|||' | tr -d '[:blank:]' | cut -d. -f3) && \ git clone https://github.com/$FRONTEND_ORG/cbioportal-frontend.git && \ cd cbioportal-frontend && \ - git fetch --tags && \ - git checkout demo-rfc72 + git fetch --tags - persist_to_workspace: root: /tmp/repos paths: diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index eb1ddd60dee..3accb07566c 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -10,15 +10,9 @@ jobs: PORTAL_INFO_DIR: /home/runner/work/cbioportal/cbioportal/portalInfo steps: - name: 'Checkout cbioportal repo' - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: path: ./cbioportal - - name: 'Install python requirements' - working-directory: ./cbioportal - run: | - sudo apt-get install python3-setuptools && \ - pip3 install -U wheel && \ - pip3 install -r ./requirements.txt - name: 'Set up JDK 21' uses: oracle-actions/setup-java@v1 with: @@ -52,11 +46,7 @@ jobs: sed 's|spring.datasource.url=.*|spring.datasource.url=jdbc:mysql://cbioportal-database:3306/cbioportal?useSSL=false|' | \ sed 's|spring.datasource.username=.*|spring.datasource.username=cbio_user|' | \ sed 's|spring.datasource.password=.*|spring.datasource.password=somepassword|' \ - > application.properties && \ - echo "db.user=cbio_user" >> application.properties && \ - echo "db.password=somepassword" >> application.properties && \ - echo "db.connection_string=jdbc:mysql://cbioportal-database:3306/cbioportal?useSSL=false" >> application.properties && \ - echo "db.driver=com.mysql.jdbc.Driver" >> application.properties + > application.properties - name: 'Copy cgds.sql file into Docker Compose' run: cp ./cbioportal/src/main/resources/db-scripts/cgds.sql ./cbioportal-docker-compose/data/. - name: 'Dump Properties' @@ -65,7 +55,7 @@ jobs: - name: 'Start cbioportal-docker-compose' working-directory: ./cbioportal-docker-compose run: | - export DOCKER_IMAGE_CBIOPORTAL=cbioportal/cbioportal:demo-rfc72-squash && docker-compose -f docker-compose.yml -f $PORTAL_SOURCE_DIR/test/integration/docker-compose-localbuild.yml up -d + docker-compose -f docker-compose.yml -f $PORTAL_SOURCE_DIR/test/integration/docker-compose-localbuild.yml up -d - name: 'Wait for cbioportal to initialize ...' id: startup uses: nev7n/wait_for_response@v1 diff --git a/.github/workflows/security-integration-test.yml b/.github/workflows/security-integration-test.yml new file mode 100644 index 00000000000..5fd20693a50 --- /dev/null +++ b/.github/workflows/security-integration-test.yml @@ -0,0 +1,36 @@ +name: Security integration tests +on: [push, pull_request] +jobs: + build: + name: Security integration tests + runs-on: ubuntu-latest + env: + PORTAL_SOURCE_DIR: /home/runner/work/cbioportal/cbioportal/cbioportal + PORTAL_COMPOSE_DIR: /home/runner/work/cbioportal/cbioportal/cbioportal-docker-compose + PORTAL_INFO_DIR: /home/runner/work/cbioportal/cbioportal/portalInfo + steps: + - name: 'Checkout cbioportal repo' + uses: actions/checkout@v2 + with: + path: ./cbioportal + - name: 'Set up JDK 21' + uses: oracle-actions/setup-java@v1 + with: + website: oracle.com + release: 21 + - name: 'Cache Maven packages' + uses: actions/cache@v1 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + - name: 'Download Chrome' + uses: browser-actions/setup-chrome@latest + - name: 'Copy Application.Properties' + working-directory: ./cbioportal + run: | + cp src/main/resources/application.properties.EXAMPLE src/main/resources/application.properties + - name: 'Run integration tests' + working-directory: ./cbioportal + run: | + mvn verify -Pintegration-test diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index bc6dc12004f..a87c052d155 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -34,6 +34,17 @@ jobs: cp src/main/resources/application.properties.EXAMPLE src/main/resources/application.properties - name: Build and analyze env: - SONAR_TOKEN: de1b5cc660cd210dde840f492c371da6cc801763 + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: mvn -DskipTests clean install verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar + run: mvn clean install verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar + - name: 'Add host.testcontainers.internal to /etc/hosts' + run: | + echo "127.0.0.1 host.testcontainers.internal" | sudo tee -a /etc/hosts + - name: 'Run integration tests' + run: | + mvn verify -Pintegration-test + - name: Code Coverage + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: mvn sonar:sonar -Pcoverage diff --git a/.github/workflows/validate-data.yml b/.github/workflows/validate-data.yml deleted file mode 100644 index 80fc0e1818f..00000000000 --- a/.github/workflows/validate-data.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Python validator -on: [push, pull_request] -jobs: - build: - name: Validate Data - runs-on: ubuntu-latest - steps: - - name: 'Checkout cbioportal repo' - uses: actions/checkout@v2 - with: - path: ./cbioportal - - name: 'Checkout core module' - uses: actions/checkout@v4 - with: - path: ./cbioportal/core - repository: cBioPortal/cbioportal-core - - name: 'Validate tests' - working-directory: ./cbioportal - run: | - docker run -v ${PWD}:/cbioportal python:3.6 /bin/sh -c ' - cd /cbioportal && - pip install -r requirements.txt && - export PYTHONPATH=/cbioportal/core/src/main/resources/scripts && - cd /cbioportal/core/src/test/scripts/ && - python unit_tests_validate_data.py && - python system_tests_validate_data.py && - python system_tests_validate_studies.py' \ No newline at end of file diff --git a/.gitignore b/.gitignore index 4dda110d9ac..c2b81971328 100644 --- a/.gitignore +++ b/.gitignore @@ -73,7 +73,7 @@ portal/src/main/webapp/WEB-INF/logback.xml !src/main/resource/*.EXAMPLE firehose-importer/reference_data/gene_info portal.properties -application.properties +src/main/resources/application.properties importer.properties log4j.properties build.properties @@ -103,7 +103,6 @@ package.json *.tramp_history pom.version.* pom.xml.* -pom.xml.* Dockerfile.local .factorypath .retype diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eb6807413ce..9d7f9299368 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -146,9 +146,8 @@ New features: ### Devops New features: -- Does the configuration style follow the config guidelines? That is compile - (Maven) config goes in the appriopriate `pom.xml` (root, `scripts/`, `portal/`, `core/`). - Runtime (Spring) goes in `portal.properties`. Default values should be in `GlobalProperties.java`. +- Does the configuration style follow the config guidelines? That is compile. +- Runtime (Spring) goes in `application.properties`. Default values should be in `GlobalProperties.java`. - Non-stable configuration should be done through war overlays. - Is the configuration tested as part of the CI tests? It's not a necessity but be aware that untested configuration will be tough to maintain. diff --git a/README.md b/README.md index afdcf952879..b9ff0081131 100644 --- a/README.md +++ b/README.md @@ -26,11 +26,9 @@ If you want to run the cBioPortal web app from the command line please follow th docker compose -f docker-compose.yml -f open-ports.yml up ``` This should open the ports. Now we are ready to run the cBioPortal web app locally. You can compile the backend code with: + ``` -export JAVA_HOME=/Library/Java/JavaVirtualMachines/temurin-11.jdk/Contents/Home/ && mvn -DskipTests clean install -``` -Note: change `JAVA_HOME` to point to a JDK 11 version. If everything compiles correctly you can then run the app like this: -``` + java -Xms2g -Xmx4g \ -Dauthenticate=noauthsessionservice \ -Dsession.service.url=http://localhost:5000/api/sessions/my_portal/ \ @@ -47,6 +45,7 @@ java -Xms2g -Xmx4g \ -cp "$PWD:$PWD/BOOT-INF/lib/*" \ org.cbioportal.PortalApplication ``` + The app should now show up at http://localhost:8080. #### Deploy your development image inside Docker Compose @@ -86,6 +85,7 @@ You can then use a JAVA IDE to connect to that port. E.g. in [VSCode](https://co ``` ## 🌳 Branch Information + | | main branch | upcoming release branch | later release candidate branch | | --- | --- | --- | --- | | Branch name | [`master`](https://github.com/cBioPortal/cbioportal/tree/master) | -- | [`rc`](https://github.com/cBioPortal/cbioportal/tree/rc) | diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000000..2fa4168533b --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,26 @@ +# Security Policy + +## Supported Versions + +We release security releases for the following versions: + +| Version | Supported | +| ------- | ------------------ | +| 6.x | :white_check_mark: | +| 5.x | :white_check_mark: | +| < 5.0 | :x: | + +## Reporting a Vulnerability +If there are any vulnerabilities, don't hesitate to report them. + +Use the private contact address cbioportal@cbioportal.org to report the fix. + +Describe the vulnerability. + +If you have a fix, that is most welcome -- please attach or summarize it in your message! + +We will evaluate the vulnerability and, if necessary, release a fix or mitigating steps to address it. We will contact you to let you know the outcome, and will credit you in the report. + +Please do not disclose the vulnerability publicly until a fix is released! + +Once we have either a) published a fix, or b) declined to address the vulnerability for whatever reason, you are free to publicly disclose it. diff --git a/dev/.env b/dev/.env new file mode 100644 index 00000000000..697e7299524 --- /dev/null +++ b/dev/.env @@ -0,0 +1,4 @@ +DOCKER_IMAGE_SESSION_SERVICE=cbioportal/session-service:0.6.1 +DOCKER_IMAGE_MYSQL=mysql:8.1.0 +DOCKER_IMAGE_KEYCLOAK=quay.io/keycloak/keycloak:23.0 +DOCKER_IMAGE_MONGODB=mongo:4.2 \ No newline at end of file diff --git a/dev/README.md b/dev/README.md new file mode 100644 index 00000000000..c23cce72e2e --- /dev/null +++ b/dev/README.md @@ -0,0 +1,58 @@ +# Tools for development + +In this folder is some additional configuration that can be useful for local development. None of this should be deployed directly to production + +# Set up keycloak for cBioPortal >v6 + +Requirements: +- System runs docker (including docker compose) + + 1. Run from the root of the repository: + +``` +cd dev +docker compose up -d +``` + +2. (Option 1) Apply SAML2 configuration to _security.properties_ in cBioPortal: + +```properties +authenticate=saml +spring.security.saml2.relyingparty.registration.keycloak.assertingparty.metadata-uri=http://localhost:8084/realms/cbio/protocol/saml/descriptor +spring.security.saml2.relyingparty.registration.keycloak.assertingparty.entity-id=http://localhost:8084/realms/cbio +spring.security.saml2.relyingparty.registration.keycloak.entity-id=cbioportal +spring.security.saml2.relyingparty.registration.keycloak.signing.credentials[0].certificate-location=classpath:/dev/security/signing-cert.pem +spring.security.saml2.relyingparty.registration.keycloak.signing.credentials[0].private-key-location=classpath:/dev/security/signing-key.pem +``` + +3. (Option 2) Apply OIDC configuration to _security.properties_ in cBioPortal: + +```properties +authenticate=oauth2 +spring.security.oauth2.client.registration.keycloak.redirect-uri=http://localhost:8080/login/oauth2/code/keycloak +spring.security.oauth2.client.registration.keycloak.client-name=cbioportal_oauth2 +spring.security.oauth2.client.registration.keycloak.client-id=cbioportal_oauth2 +spring.security.oauth2.client.registration.keycloak.client-secret=client_secret +spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code +spring.security.oauth2.client.registration.keycloak.client-authentication-method=client_secret_post +spring.security.oauth2.client.registration.keycloak.scope=openid,email,roles +spring.security.oauth2.client.provider.keycloak.issuer-uri=http://localhost:8084/realms/cbio +spring.security.oauth2.client.provider.keycloak.user-name-attribute=email +``` + +4. Set the following in _application.properties_: + +```properties +persistence.cache_type=no-cache +session.service.url=http://localhost:5000/api/sessions/my_portal/ + +spring.datasource.url=jdbc:mysql://localhost:3306/cbioportal?useSSL=false&allowPublicKeyRetrieval=true +spring.datasource.username=cbio_user +spring.datasource.password=somepassword +spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect +spring.datasource.driver-class-name=com.mysql.jdbc.Driver +``` + +4. Start cBioPortal application on port 8080. The login credentials are `testuser:P@assword1`. + +⚠️ Warning: Do not use this directly for production use as it takes several shortcuts to get a quick keycloak instance up. diff --git a/dev/docker-compose.yml b/dev/docker-compose.yml new file mode 100644 index 00000000000..3a4d72b47b6 --- /dev/null +++ b/dev/docker-compose.yml @@ -0,0 +1,57 @@ +version: '3' + +services: + cbioportal-database: + restart: unless-stopped + image: ${DOCKER_IMAGE_MYSQL} + container_name: cbioportal-database + environment: + MYSQL_DATABASE: cbioportal + MYSQL_USER: cbio_user + MYSQL_PASSWORD: somepassword + MYSQL_ROOT_PASSWORD: somepassword + volumes: + - $PWD/../src/main/resources/db-scripts/cgds.sql:/docker-entrypoint-initdb.d/cgds.sql:ro + - $PWD/../src/test/resources/seed_mini.sql:/docker-entrypoint-initdb.d/seed.sql:ro + ports: + - 3306:3306 + cbioportal-session: + restart: unless-stopped + image: ${DOCKER_IMAGE_SESSION_SERVICE} + container_name: cbioportal-session + environment: + SERVER_PORT: 5000 + JAVA_OPTS: -Dspring.data.mongodb.uri=mongodb://cbioportal-session-database:27017/session-service + depends_on: + - cbioportal-session-database + ports: + - 5000:5000 + networks: + - cbio-net + cbioportal-session-database: + restart: unless-stopped + image: ${DOCKER_IMAGE_MONGODB} + container_name: cbioportal-session-database + environment: + MONGO_INITDB_DATABASE: session-service + networks: + - cbio-net + keycloak: + restart: unless-stopped + container_name: keycloak + image: ${DOCKER_IMAGE_KEYCLOAK} + volumes: + - $PWD/../src/main/resources/dev/security/keycloak-configuration-generated.json:/opt/keycloak/data/import/realm.json:ro + environment: + - KC_HOSTNAME=localhost + - KC_DB_USERNAME=keycloak + - KC_DB_PASSWORD=password + - KC_DB_DATABASE=keycloak + - KEYCLOAK_ADMIN=admin + - KEYCLOAK_ADMIN_PASSWORD=admin + ports: + - 8084:8080 + command: start-dev --import-realm + +networks: + cbio-net: \ No newline at end of file diff --git a/docker/web-and-data/Dockerfile b/docker/web-and-data/Dockerfile index 5252f98b4d9..b1021c6db08 100644 --- a/docker/web-and-data/Dockerfile +++ b/docker/web-and-data/Dockerfile @@ -45,15 +45,14 @@ RUN apt-get update; apt-get install -y --no-install-recommends \ RUN mkdir -p /cbioportal #Download core files -RUN wget https://github.com/cBioPortal/cbioportal-core/releases/download/1.0.4/core-1.0.4.jar -P core/ ; cd core ; jar -xf core-1.0.4.jar scripts/ ; chmod -R a+x scripts/ ; cd ..; +RUN wget https://github.com/cBioPortal/cbioportal-core/releases/download/1.0.6/core-1.0.6.jar -P core/ ; cd core ; jar -xf core-1.0.6.jar scripts/ requirements.txt ; chmod -R a+x scripts/ ; cd ..; COPY --from=build /cbioportal/src/main/resources/db-scripts /cbioportal/db-scripts -COPY --from=build /cbioportal/requirements.txt /cbioportal/requirements.txt # install build and runtime dependencies # ignore update failure980[1298[01 w2308s -RUN pip3 install -r /cbioportal/requirements.txt +RUN pip3 install -r /core/requirements.txt # add importer scripts to PATH for easy running in containers RUN find /core/scripts/ -type f -executable \! -name '*.pl' -print0 | xargs -0 -- ln -st /usr/local/bin @@ -75,4 +74,4 @@ COPY --from=build ${DEPENDENCY}/BOOT-INF/classes $PORTAL_WEB_HOME/ # add entrypoint COPY --from=build /cbioportal/docker/web-and-data/docker-entrypoint.sh /usr/local/bin/ ENTRYPOINT ["docker-entrypoint.sh"] -CMD ["sh", "-c", "java $(echo $JAVA_OPTS) -cp /cbioportal-webapp:/cbioportal-webapp/lib/* org.cbioportal.PortalApplication $(echo $WEBAPP_OPTS)"] \ No newline at end of file +CMD ["sh", "-c", "java $(echo $JAVA_OPTS) -cp /cbioportal-webapp:/cbioportal-webapp/lib/* org.cbioportal.PortalApplication $(echo $WEBAPP_OPTS)"] diff --git a/docker/web-and-data/docker-entrypoint.sh b/docker/web-and-data/docker-entrypoint.sh index 5c78c46ac53..a0cd507d5b7 100755 --- a/docker/web-and-data/docker-entrypoint.sh +++ b/docker/web-and-data/docker-entrypoint.sh @@ -14,7 +14,7 @@ _is_sourced() { } parse_db_params_from_command_line() { - echo $@ | sed 's/-D/\n-D/g' | grep -- '-Ddb' | sed 's/-D//g' | grep db. + echo $@ | sed 's/-D/\n-D/g' | grep -- '-Dspring' | sed 's/-D//g' | grep db. } parse_db_params_from_config_and_command_line() { @@ -23,7 +23,7 @@ parse_db_params_from_config_and_command_line() { else PROPERTIES_FILE=$BAKED_IN_WAR_CONFIG_FILE fi - for param in db.host db.user db.portal_db_name db.password db.connection_string; do + for param in db.host spring.datasource.username db.portal_db_name spring.datasource.password spring.datasource.url; do if $(parse_db_params_from_command_line $@ | grep -q $param); then prop=$(parse_db_params_from_command_line $@ | grep "^$param" || [[ $? == 1 ]]) else @@ -32,8 +32,12 @@ parse_db_params_from_config_and_command_line() { if [[ -n "$prop" ]] then # Replace dot in parameter name with underscore. - prop=$(sed "s/^db\./db_/" <<< $prop) - if [[ $param == db.connection_string ]] + #prop=$(sed "s/\([^=]*\)\./\1_/g" <<< "$prop") + before_equal_sign="${prop%%=*}" + after_equal_sign="${prop#*=}" + updated_before_equal_sign="${before_equal_sign//./_}" + prop="${updated_before_equal_sign}=${after_equal_sign}" + if [[ $param == spring.datasource.url ]] then # Remove the parameters (?...) from the connection URL. echo $(sed -r "s/^([^=]+)=([^\?]+).*/\1=\2/" <<< $prop) @@ -64,7 +68,7 @@ check_db_connection() { echo "----------------------------------------------------------------------------------------------------------------" echo "-- Connection error:" echo "-- You try to connect to the database using the deprecated 'db.host', 'db.portal_db_name' and 'db.use_ssl' properties." - echo "-- Please remove these properties and use the 'db.connection_string' property instead. See https://docs.cbioportal.org/deployment/customization/portal.properties-reference/" + echo "-- Please remove these properties and use the 'db.connection_string' property instead. See https://docs.cbioportal.org/deployment/customization/application.properties-reference/" echo "-- for assistance on building a valid connection string." echo "------------------------------------------------------------f---------------------------------------------------" exit 1 @@ -74,6 +78,11 @@ check_db_connection() { then eval "$(parse_connection_string $db_connection_string)" fi + + if [[ -n $spring_datasource_url ]] + then + eval "$(parse_connection_string $spring_datasource_url)" + fi if [ -z ${db_port+x} ] # is $db_port unset? then @@ -84,11 +93,11 @@ check_db_connection() { fi fi - while ! mysqladmin ping -s -h$(echo ${db_host} | cut -d: -f1) -P${db_port} -u${db_user} -p${db_password}; + while ! mysqladmin ping -s -h$(echo ${db_host} | cut -d: -f1) -P${db_port} -u${spring_datasource_username} -p${spring_datasource_password}; do sleep 5s; if [ -n "$SHOW_DEBUG_INFO" ] && [ "$SHOW_DEBUG_INFO" != "false" ]; then - echo mysqladmin ping -s -h$(echo ${db_host} | cut -d: -f1) -P${db_port} -u${db_user} -p${db_password} + echo mysqladmin ping -s -h$(echo ${db_host} | cut -d: -f1) -P${db_port} -u${spring_datasource_username} -p${spring_datasource_password} fi echo "Database not available yet (first time can take a few minutes to load seed database)... Attempting reconnect..." done @@ -102,7 +111,7 @@ migrate_db() { if [[ -f $CUSTOM_PROPERTIES_FILE ]]; then python3 /core/scripts/migrate_db.py -y -p $CUSTOM_PROPERTIES_FILE -s /cbioportal/db-scripts/migration.sql else - python3 /core/migrate_db.py -y -p <(parse_db_params_from_config_and_command_line $POTENTIAL_DB_PARAMS) -s /cbioportal/db-scripts/migration.sql + python3 /core/scripts/migrate_db.py -y -p <(parse_db_params_from_config_and_command_line $POTENTIAL_DB_PARAMS) -s /cbioportal/db-scripts/migration.sql fi } @@ -128,7 +137,7 @@ _main() { echo "Running Migrate DB Script" # Custom logic to handle the case when "org.cbioportal.PortalApplication" is present # Parse database config. Use command line parameters (e.g. -Ddb.host) if - # available, otherwise use portal.properties + # available, otherwise use application.properties if [ -n "$SHOW_DEBUG_INFO" ] && [ "$SHOW_DEBUG_INFO" != "false" ]; then echo "Using database config:" parse_db_params_from_config_and_command_line $@ diff --git a/docs/404.md b/docs/404.md index 254789fc310..2179e87d107 100644 --- a/docs/404.md +++ b/docs/404.md @@ -32,7 +32,8 @@ window.redirectMap = { "2.2-authorization-and-authentication/authenticating-and-authorizing-users-via-keycloak":"deployment/authorization-and-authentication/authenticating-and-authorizing-users-via-keycloak", "2.2-authorization-and-authentication/authenticating-users-via-tokens":"deployment/authorization-and-authentication/authenticating-users-via-tokens", "2.3-customization/customizing-your-instance-of-cbioportal":"deployment/customization/customizing-your-instance-of-cbioportal", - "2.3-customization/portal.properties-reference":"deployment/customization/portal.properties-reference", + "2.3-customization/portal.properties-reference":"deployment/customization/application.properties-reference/", + "deployment/customization/portal.properties-reference":"deployment/customization/application.properties-reference/", "2.3-customization/caching":"deployment/customization/caching", "2.3-customization/layout":"deployment/customization/studyview/#how-does-the-study-view-organize-the-charts", "2.3-customization/priority":"deployment/customization/studyview/#study-view-customization-with-priority-data", diff --git a/docs/Architecture-Overview.md b/docs/Architecture-Overview.md index fa6d01c2f2f..8f54bc36ddd 100644 --- a/docs/Architecture-Overview.md +++ b/docs/Architecture-Overview.md @@ -74,7 +74,7 @@ relevance of variants (or biomarker alterations) in cancer. For information on how to deploy this service yourself see: https://github.com/griffithlab/civic-server. It is also possible to disable showing CIVIC in cBioPortal by setting `show.civic=false` in the -`portal.properties` (See [portal.properties reference](/deployment/customization/portal.properties-Reference.md#civic-integration)). +`application.properties` (See [application.properties reference](/deployment/customization/application.properties-Reference.md#civic-integration)). ### Genome Nexus [Genome Nexus](https://www.genomenexus.org) is a comprehensive one-stop diff --git a/docs/File-Formats.md b/docs/File-Formats.md index 797ed1b0505..0c7c1d7eb84 100644 --- a/docs/File-Formats.md +++ b/docs/File-Formats.md @@ -47,7 +47,7 @@ This file contains metadata about the cancer study. The file contains the follow 7. **groups (Optional)**: When using an authenticating cBioPortal, lists the user-groups that are allowed access to this study. Multiple groups are separated with a semicolon ";". The study will be invisible to users not in _at least one_ of the listed groups, as if it wasn't loaded at all. e.g., "PUBLIC;GDAC;SU2C-PI3K". see [User-Authorization](/deployment/authorization-and-authentication/User-Authorization.md) for more information on groups 8. **add_global_case_list (Optional)**: set to 'true' if you would like the "All samples" case list to be generated automatically for you. See also [Case lists](#case-lists). 9. **tags_file (Optional)**: the file name containing custom study tags for the [study tags](#study-tags-file). -10. **reference_genome (Optional)**: the study reference genome (e.g. `hg19`, `hg38`). Without specifying this property, the study will be assigned to the reference genome specified in `portal.properties` (property `ucsc.build`). +10. **reference_genome (Optional)**: the study reference genome (e.g. `hg19`, `hg38`). Without specifying this property, the study will be assigned to the reference genome specified in `application.properties` (property `ucsc.build`). ### Example An example meta_study.txt file would be: @@ -403,7 +403,7 @@ All genes referenced in the custom driver annotation file must be present in the The `cbp_driver` column flags the mutation as either driver or passenger. In cBioPortal, passenger mutations are also known as variants of unknown significance (VUS). The `cbp_driver_tiers` column assigns an annotation tier to the mutation, such as "Driver", "Highly actionable" or "Potential drug target". When a tier is selected, mutations with that annotation are highlighted as driver. Both types of custom annotations contain a second column with the suffix `_annotation`, to add a description. This is displayed in the tooltip that appears when hovering over the sample's custom annotation icon in the OncoPrint view. -You can learn more about configuring these annotations in the [portal.properties documentation](/deployment/customization/portal.properties-Reference.md#custom-annotation-of-driver-and-passenger-mutations). When properly configured, the customized annotations appear in the "Mutation Color" menu of the OncoPrint view: \ +You can learn more about configuring these annotations in the [application.properties documentation](/deployment/customization/application.properties-Reference.md#custom-annotation-of-driver-and-passenger-mutations). When properly configured, the customized annotations appear in the "Mutation Color" menu of the OncoPrint view: \ ![schreenshot mutation color menu](images/screenshot-mutation-color-menu.png) ### Example @@ -769,7 +769,7 @@ It is possible to manually add columns for defining custom driver annotations. T The `cbp_driver` column flags the mutation as either driver or passenger. In cBioPortal, passenger mutations are also known as variants of unknown significance (VUS). The `cbp_driver_tiers` column assigns an annotation tier to the mutation, such as "Driver", "Highly actionable" or "Potential drug target". When a tier is selected, mutations with that annotation are highlighted as driver. Both types of custom annotations contain a second column with the suffix `_annotation`, to add a description. This is displayed in the tooltip that appears when hovering over the sample's custom annotation icon in the OncoPrint view. -You can learn more about configuring these annotations in the [portal.properties documentation](/deployment/customization/portal.properties-Reference.md#custom-annotation-of-driver-and-passenger-mutations). When properly configured, the customized annotations appear in the "Mutation Color" menu of the OncoPrint view: \ +You can learn more about configuring these annotations in the [application.properties documentation](/deployment/customization/application.properties-Reference.md#custom-annotation-of-driver-and-passenger-mutations). When properly configured, the customized annotations appear in the "Mutation Color" menu of the OncoPrint view: \ ![schreenshot mutation color menu](/images/screenshot-mutation-color-menu.png) ### Adding your own mutation annotation columns diff --git a/docs/Hardware-Requirements.md b/docs/Hardware-Requirements.md index 11523c1520a..4746fef4c20 100644 --- a/docs/Hardware-Requirements.md +++ b/docs/Hardware-Requirements.md @@ -22,4 +22,4 @@ Another possible consideration is caching. The portal can cache responses to requests so that repeated database queries are avoided. On the public cBioPortal deployment we enable this cache and allocate 1GB of additional RAM and 4GB of additional disk space for caching. For directions on configuring caching, see -[Ehcache Settings](/deployment/customization/portal.properties-Reference.md#cache-settings) +[Ehcache Settings](/deployment/customization/application.properties-Reference.md#cache-settings) diff --git a/docs/Import-Gene-Panels.md b/docs/Import-Gene-Panels.md index 4ecbd393f04..6fdaa6fc6f3 100644 --- a/docs/Import-Gene-Panels.md +++ b/docs/Import-Gene-Panels.md @@ -30,7 +30,7 @@ cd /core/src/main/scripts ``` After loading gene panels into the database, please restart Tomcat or call the `/api/cache` endpoint with a `DELETE` http-request -(see [here](/deployment/customization/portal.properties-Reference.md#cache-settings) for more information) so that the +(see [here](/deployment/customization/application.properties-Reference.md#cache-settings) for more information) so that the validator can retrieve gene panel information from the cBioPortal API. #### Update existing gene panel diff --git a/docs/Import-Gene-Sets.md b/docs/Import-Gene-Sets.md index 6a778897b2d..f6e0b7ed0bb 100644 --- a/docs/Import-Gene-Sets.md +++ b/docs/Import-Gene-Sets.md @@ -31,7 +31,7 @@ Note: This removes existing gene set, gene set hierarchy and gene set genetic pr ``` 4. Restart Tomcat if you have it running or call the `/api/cache` endpoint with a `DELETE` http-request - (see [here](/deployment/customization/portal.properties-Reference.md#evict-caches-with-the-apicache-endpoint) for more information). + (see [here](/deployment/customization/application.properties-Reference.md#evict-caches-with-the-apicache-endpoint) for more information). 5. Import study (replace argument after `-u` with local cBioPortal and `-html` with preferred location for html report): diff --git a/docs/Import-Study-Using-Docker.md b/docs/Import-Study-Using-Docker.md index 5770bd22764..4b350ba6422 100644 --- a/docs/Import-Study-Using-Docker.md +++ b/docs/Import-Study-Using-Docker.md @@ -1,7 +1,7 @@ # Import Study Using Docker :warning: Every time you add/remove/overwrite a study please restart tomcat (or the Docker container), or -call the `/api/cache` endpoint with a `DELETE` http-request (see [here](/deployment/customization/portal.properties-Reference.md#evict-caches-with-the-apicache-endpoint) for more information). +call the `/api/cache` endpoint with a `DELETE` http-request (see [here](/deployment/customization/application.properties-Reference.md#evict-caches-with-the-apicache-endpoint) for more information). ## Adding a Study diff --git a/docs/Inter-Repository-Dependencies.md b/docs/Inter-Repository-Dependencies.md new file mode 100644 index 00000000000..7ac1dc38270 --- /dev/null +++ b/docs/Inter-Repository-Dependencies.md @@ -0,0 +1,72 @@ +# Inter-Repository Dependencies + +## cbioportal-core Repository + +[cbioportal-core](https://github.com/cBioPortal/cbioportal-core) is dependent on +[cbioportal](https://github.com/cBioPortal/cbioportal). +This can be seen in its [pom.xml](https://github.com/cBioPortal/cbioportal-core/blob/main/pom.xml). +By removing the dependency and attempting to build cbioportal-core, errors are reported. This +document captures a summary of the reported errors. This analysis was done at the time of release +v6.0.0. + +cbioportal-core now primarily provides import functionality, which is mainly located +in the packages: +- [org.mskcc.cbio.portal.dao](https://github.com/cBioPortal/cbioportal-core/tree/main/src/main/java/org/mskcc/cbio/portal/dao) +- [org.mskcc.cbio.portal.model](https://github.com/cBioPortal/cbioportal-core/tree/main/src/main/java/org/mskcc/cbio/portal/model) +- [org.mskcc.cbio.portal.scripts](https://github.com/cBioPortal/cbioportal-core/tree/main/src/main/java/org/mskcc/cbio/portal/scripts) + +### Dependencies in cbioportal-core import functionality + +Code in cbioportal which is referenced directly by code in cbioportal-core consists of three +enum class definitions. + +- cbioportal class [ResourceType](https://github.com/cBioPortal/cbioportal/blob/master/src/main/java/org/cbioportal/model/ResourceType.java) is imported by cbioportal-core class [ResourceDefinition](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/model/ResourceDefinition.java). This provides enum constants {STUDY, SAMPLE, PATIENT}. +- cbioportal class [EntityType](https://github.com/cBioPortal/cbioportal/blob/master/src/main/java/org/cbioportal/model/EntityType.java) is imported by cbioportal-core class [ImportTabDelimData](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/scripts/ImportTabDelimData.java). This provides enum constants {GENE, GENESET, PHOSPHOPROTEIN, GENERIC_ASSAY}. +- cbioportal class [CNA](https://github.com/cBioPortal/cbioportal/blob/master/src/main/java/org/cbioportal/model/CNA.java) is imported by cbioportal-core class [CnaEvent](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/model/CnaEvent.java). This provides enum constants {AMP, GAIN, DIPLOID, HETLOSS, HOMDEL}. + +The cbioportal-core import functionality code also relies on several packaged libraries in cbioportal. + +cbioportal packaged library org.apache.commons.commons-collections4 (version 4.4) is used by these cbioportal-core classes: +- [DaoPatient](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/dao/DaoPatient.java) +- [ImportClinicalData](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/scripts/ImportClinicalData.java) + +cbioportal packaged library org.slf4j.slf4j-api (latest version) is used by these cbioportal-core classes: +- [JdbcUtil](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/dao/JdbcUtil.java) +- [ProgressMonitor](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/util/ProgressMonitor.java) +- [Patient](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/model/Patient.java) +- [AccessControlImpl](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/util/internal/AccessControlImpl.java) + +cbioportal packaged library org.springframework.security.spring-security.core (latest compatible version) +and other related such as org.springframework.security.spring-security.web are used in these cbioportal-core classes: +- [AccessControl](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/util/AccessControl.java) +- [DaoCancerStudy](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/dao/DaoCancerStudy.java) (transitive dependency through AccessControl) + +### Other dependencies in cbioportal-core + +There are other (non-import) cbioportal-core uses of libraries packaged in cbioportal. + +cbioportal packaged libraries jakarta.servlet jakarta.servlet.http (ServletConfig, HttpServlet, ServletException, HttpServletRequest, HttpServletResponse} are used by these cbioportal-core classes: +- [GetSurvivalDataJSON](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/servlet/GetSurvivalDataJSON.java) +- [XDebug](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/util/XDebug.java) +- [CalcCoExp](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/servlet/CalcCoExp.java) +- [BioGeneServlet](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/servlet/BioGeneServlet.java) +- [IGVLinkingJSON](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/servlet/IGVLinkingJSON.java) + +cbioportal packaged library org.json.simple / com.googlecode.json-simple.json-simple (version 1.1.1) is used by these cbioportal-core classes: +- [CalcCoExp](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/servlet/CalcCoExp.java) +- [GetSurvivalDataJSON](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/servlet/GetSurvivalDataJSON.java) +- [IGVLinkingJSON](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/servlet/IGVLinkingJSON.java) +- [GetClinicalData](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/web_api/GetClinicalData.java) + +cbioportal packaged library org.apache.commonsorg.apache.commons.commons-math3 (version 3.6.1) is used by this cbioportal-core class: +- [CalcCoExp](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/servlet/CalcCoExp.java) + +cbioportal packaged library org.slf4j.slf4j-api (latest version) is used by this cbioportal-core class: +- [AccessControlImpl](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/util/internal/AccessControlImpl.java) (transitive dependency through many servlets) + +cbioportal packaged library org.springframework.security.spring-security.core (latest compatible version) +and other related such as org.springframework.security.spring-security.web are used in these cbioportal-core classes: +- [AccessControl](https://github.com/cBioPortal/cbioportal-core/blob/main/src/main/java/org/mskcc/cbio/portal/util/AccessControl.java) (transitive dependency through many servlets) + +### Consequences +When any of these dependencies are updated in cbioportal (or in the case of libraries, updated in a non-backwards-compatible way), the cbioportal-core repository should be built and tested using the updated dependencies and proper behavior of the import functionality should be tested. cbioportal-core should also be brought up to date by packaging the current version of cbioportal into cbioportal-core (in pom.xml). diff --git a/docs/MSK-Maintenance.md b/docs/MSK-Maintenance.md index 95542077e99..47f58653c24 100644 --- a/docs/MSK-Maintenance.md +++ b/docs/MSK-Maintenance.md @@ -61,10 +61,10 @@ Database needs to be updated one by one, we have four main databases: triage, pr - SSH into pipeline server - Checkout to the commit that contains the latest database scheme - Check if property sets up correctly to the right database (triage) - - `vi /data/portal-cron/git-repos/cbioportal/src/main/resources/portal.properties` + - `vi /data/portal-cron/git-repos/cbioportal/src/main/resources/application.properties` - Move to directory - `cd /data/portal-cron/git-repos/cbioportal` - Run database migration using script: - - `python3 core/src/main/scripts/migrate_db.py --properties-file src/main/resources/portal.properties --sql db-scripts/src/main/resources/migration.sql` + - `python3 core/src/main/scripts/migrate_db.py --properties-file src/main/resources/application.properties --sql db-scripts/src/main/resources/migration.sql` - Monitor the DB migration process and look for possible errors - Access database and verify the DB scheme is updated diff --git a/docs/News-Genie.md b/docs/News-Genie.md index 1986538ac4b..b406df988b1 100644 --- a/docs/News-Genie.md +++ b/docs/News-Genie.md @@ -1,4 +1,12 @@ # Genie News +## April 3, 2024 +* **Public Release 15.1 of AACR Project GENIE:** + * The public release 15.1 version of AACR GENIE has 61 samples retracted that were present in AACR GENIE 15.0-public. + * More detailed information can be found in the [AACR GENIE release notes](https://www.synapse.org/#!Synapse:syn55234828) and the data releases page from [Sage Bionetworks](https://www.synapse.org/#!Synapse:syn55234548). +## January 9, 2024 +* **Public Release 15.0 of AACR Project GENIE:** + * The first set of cancer genomic data aggregated through AACR Project Genomics Evidence Neoplasia Information Exchange (GENIE) was released to the global community in January 2017. The current release, GENIE 15.0-public now contains over 198,000 sequenced samples from over 172,000 patients, making the AACR Project GENIE registry among the largest fully public cancer genomic data sets. + * More detailed information can be found in the [AACR GENIE Data Guide](https://www.synapse.org/#!Synapse:syn7222066/wiki/409237). In addition to accessing the data via the cBioPortal, users can download the data directly from [Sage Bionetworks](http://synapse.org/genie). Users will need to create an account for either site and agree to the [terms of access](https://www.synapse.org/#!Synapse:syn50898929). ## November 9, 2023 * **Public Release 14.1 of AACR Project GENIE:** * The public release 14.1 version of AACR GENIE has 10 samples retracted that were present in AACR GENIE 14.0-public. diff --git a/docs/News.md b/docs/News.md index 864d3058488..d3ee0877bf4 100644 --- a/docs/News.md +++ b/docs/News.md @@ -1,6 +1,74 @@ +## Apr 2, 2024 +* **Introducing the cBioPortal Newsletter!** Stay updated with the latest developments, insights, and community highlights of cBioPortal. Subscribe via [LinkedIn](https://www.linkedin.com/pulse/april-update-hello-cbioportal-community-cbioportal-22vle/) or [google groups](https://groups.google.com/g/cbioportal-news). We'll be sharing valuable updates every few months. + +## Mar 5, 2024 +* **Local Installations Feature**: Make representation of custom driver annotation configurable: + ![image](https://github.com/cBioPortal/cbioportal/assets/1334004/f67fd82f-1789-4427-9ca1-f17fc70c1a09) + +## Feb 7, 2024 +* **New feature**: The _Datasets Page_ now lists what studies have samples profiled for Structural Variants: + + ![image](https://github.com/cBioPortal/cbioportal/assets/1334004/0e4e73e4-d9d8-417d-912c-710163480905) + +* **New Major Release**: **v6.0.0** includes a major repackaging of the backend software to improve the development experience. The backend has been upgraded to use Java Spring Boot v3.1.4. The CORE and MAF modules have been moved to new repositories. All other modules have been compacted into a single source repository. We have also updated the JVM to 21 and many libraries have been updated to address security and performance issues. See more information in the [v6.0.0 release notes](https://github.com/cBioPortal/cbioportal/releases/tag/v6.0.0). + +* **Local Installations Feature**: When mutational signature data is loaded, show COSMIC reference signatures on the _Patient View_: + + ![image](https://github.com/cBioPortal/cbioportal/assets/1334004/10f73baa-d28c-4bb7-ad62-4751bd7f61cd) + +## Dec 29, 2023 +* **Added data** consisting of 5,120 samples from 13 studies: + * [Endometrial Cancer (MSK, Cancer Discovery 2023)](https://www.cbioportal.org/study/summary?id=ucec_ancestry_cds_msk_2023) *1882 samples* + * [Esophagogastric Cancer (MSK, J Natl Cancer Inst 2023)](https://www.cbioportal.org/study/summary?id=egc_msk_2023) *902 samples* + * [Diffuse Glioma (GLASS Consortium, 2022)](https://www.cbioportal.org/study/summary?id=difg_glass) *693 samples* + * [Bladder Cancer (MSK, Clin Cancer Res 2023)](https://www.cbioportal.org/study/summary?id=bladder_msk_2023) *526 samples* + * [Non-Small Cell Lung Cancer Brain Metastasis (MSK, Nat Commun 2023)](https://www.cbioportal.org/study/summary?id=bm_nsclc_mskcc_2023) *322 samples* + * [MSK Make-an-IMPACT Rare Cancers (MSK, Clin Cancer Res 2023)](https://www.cbioportal.org/study/summary?id=makeanimpact_ccr_2023) *184 samples* + * [Cervical Cancer (MSK, Clin Cancer Res 2023)](https://www.cbioportal.org/study/summary?id=cervix_msk_2023) *177 samples* + * [Mature T and NK Neoplasms (MSK, Blood Adv 2023)](https://www.cbioportal.org/study/summary?id=mtnn_msk_2022) *132 samples* + * [Hepatocellular Carcinoma (MSK, JCO Precis Oncol 2023)](https://www.cbioportal.org/study/summary?id=hcc_jcopo_msk_2023) *90 samples* + * [Sarcoma (MSK, J Pathol 2023)](https://www.cbioportal.org/study/summary?id=sarcoma_msk_2023) *82 samples* + * [Esophagogastric Cancer (MSK, Clin Cancer Res 2023)](https://www.cbioportal.org/study/summary?id=egc_trap_ccr_msk_2023) *64 samples* + * [Rhabdomyosarcomas (MSK, NPJ Precis Oncol 2023)](https://www.cbioportal.org/study/summary?id=soft_tissue_msk_2023) *42 samples* + * [Pediatric Rhabdomyosarcomas (MSK, JCO Precis Oncol 2023)](https://www.cbioportal.org/study/summary?id=rms_msk_2023) *24 samples* + +* **Gene Tables Update:** Updated tables of genes (main and alias), based on [Oct 1, 2023 HGNC release](http://ftp.ebi.ac.uk/pub/databases/genenames/hgnc/archive/monthly/tsv/). See seedDB release notes [here](https://github.com/cBioPortal/datahub/tree/master/seedDB#latest-seed-database-schema-2131) for details. + +## Dec 5, 2023 +* **New feature**: Filter by data types on the homepage: + + ![image](https://github.com/cBioPortal/cbioportal/assets/1334004/cf6d5486-bfd7-4f69-add0-442dbb4d354a) +* **New feature**: Change colors of tracks in Oncoprint: + + + +* **New feature**: Show alteration frequencies per group in OncoPrint. [Example: RTK-RAS alterations in Smokers vs Never Smokers Lung Cancer Cases in MSK-IMPACT Clinical Sequencing Cohort](https://bit.ly/3PwKsDJ) + + + +## Oct 17, 2023 +* **New feature**: Survival charts with landmark events and hazard ratios. [Example: TP53 in Lung Cancer Cases in MSK-IMPACT Clinical Sequencing Cohort](https://bit.ly/48QktxS) + + + +## Oct 3, 2023 +* **New feature**: New Structural Variants Tab on _Results View_. [Example: TMPRSS2 Structural Variants in MSK-IMPACT Clinical Sequencing Cohort](https://bit.ly/49FDhRk) + + + +## Sep 5, 2023 +* **New feature**: Add gene-specific CNA charts to show all levels of copy number alterations (including gain and hetloss) on _Study View_: + + + +## Aug 30, 2023 +* **Enhancement**: Exclude a patient from your selection directly from the _Patient View_: + + ![image](https://github.com/cBioPortal/cbioportal/assets/1334004/501fe998-8408-48e3-a183-e27ab3ff3f28) + ## Aug 21, 2023 * **Added data** consisting of 4,488 samples from 7 studies: - * [Lung Adenocarcinoma Met Organotropism (MSK, Cancer Cell 2023)](https://www.cbioportal.org/study/summary?id=luad_mskcc_2023_met_organotropism) *2653 samples* + * [Lung Adenocarcinoma Met Organotropism (MSK, Cancer Cell 2023)](https://www.cbioportal.org/study/summary?id=luad_mskcc_2023_met_organotropism) *2653 samples* * [Acute Myeloid Leukemia (OHSU, Cancer Cell 2022)](https://www.cbioportal.org/study/summary?id=aml_ohsu_2022) *942 samples* * [Colon Cancer (Sidra-LUMC AC-ICAM, Nat Med 2023)](https://www.cbioportal.org/study/summary?id=coad_silu_2022) *348 samples* * [Pediatric Neuroblastoma (MSK, Nat Genet 2023)](https://www.cbioportal.org/study/summary?id=nbl_msk_2023) *223 samples* @@ -8,11 +76,12 @@ * [Bladder Cancer (Columbia University/MSK, Cell 2018)](https://www.cbioportal.org/study/summary?id=bladder_columbia_msk_2018) *130 samples* * [Myoepithelial Carcinomas of Soft Tissue (WCM, CSH Molecular Case Studies 2022)](https://www.cbioportal.org/study/summary?id=stmyec_wcm_2022) *12 samples* -* **Gene Tables Update** Updated tables of genes (main and alias), based on [Apr 1, 2023 HGNC release](http://ftp.ebi.ac.uk/pub/databases/genenames/hgnc/archive/monthly/tsv/). See seedDB release note [here](https://github.com/cBioPortal/datahub/tree/master/seedDB#latest-seed-database) for details. + +* **Gene Tables Update:** Updated tables of genes (main and alias), based on [Apr 1, 2023 HGNC release](http://ftp.ebi.ac.uk/pub/databases/genenames/hgnc/archive/monthly/tsv/). See seedDB release notes [here](https://github.com/cBioPortal/datahub/tree/master/seedDB#latest-seed-database) for details. ## Aug 1, 2023 * **Enhancement**: One-sided Fisher's exact tests were changed to be two-sided. The affected pages are: - * Results View Page - Mutual Exclusivity Tab + * Results View Page - Mutual Exclusivity Tab * Results View Page - Comparison Tab - Genomic Alterations Tab * Comparison Page - Genomic Alterations Tab * Comparison Page - Mutations Tab @@ -21,12 +90,23 @@ Several users pointed out that using a one-sided test was incorrect for these comparisons. Please see discussions [here](https://github.com/cBioPortal/cbioportal/issues/9943) for more information. +## Jul 18, 2023 +* **New Feature**: Add mutations table and two-sided exact p-value to comparison. [Example: AR mutations in Primary vs Metastatic Prostate Cancer samples in MSK-IMPACT Clinical Sequencing Cohort](https://www.cbioportal.org/comparison/mutations?sessionId=5cf89323e4b0ab413787436c&groupOrder=%5B%22Primary%22%2C%22Metastasis%22%5D&selectedGene=AR) + + + + ## May 2, 2023 * **New Feature**: The mutations tab now shows variant annotations from the [repository of Variant with Unexpected Effects (reVUE)](https://www.cancerrevue.org/). + +## Apr 25, 2023 +* **Local Installations Feature**: When custom driver annotations for structural variants are loaded, one can now filter by them in both the Oncoprint and the _Study View_. + ## Apr 11, 2023 * **New Feature**: Disable autocommit and manually commit filters in study view. Manually commit filters can improve cBioPortal performance when query large dataset. + @@ -43,21 +123,23 @@ ## Apr 4, 2023 * **New Feature**: Allow numeric data type for custom data charts. + This also allows to have numerical custom data after we query based on genes (custom data 2 in the image): + ## Jan 10, 2023 -* **New Feature**: New Pathways tab on the Group Comparison view. - [Example: Primary vs Metastasis samples in MSK-IMPACT Clinical Sequencing Cohort](https://www.cbioportal.org/comparison/pathways?comparisonId=61791fa92e3200072db9b64e&groupOrder=%5B%22Primary%22%2C%22Metastasis%22%5D) +* **New Feature**: New Pathways tab on the Group Comparison view. [Example: Primary vs Metastasis samples in MSK-IMPACT Clinical Sequencing Cohort](https://www.cbioportal.org/comparison/pathways?comparisonId=61791fa92e3200072db9b64e&groupOrder=%5B%22Primary%22%2C%22Metastasis%22%5D) + ## Dec 13, 2022 -* **New Feature**: New Mutations tab on the Group Comparison view. - [Example: Primary vs Metastasis samples in MSK-IMPACT Clinical Sequencing Cohort](https://www.cbioportal.org/comparison/mutations?comparisonId=61791fa92e3200072db9b64e&groupOrder=%5B%22Primary%22%2C%22Metastasis%22%5D) +* **New Feature**: New Mutations tab on the Group Comparison view. [Example: Primary vs Metastasis samples in MSK-IMPACT Clinical Sequencing Cohort](https://www.cbioportal.org/comparison/mutations?comparisonId=61791fa92e3200072db9b64e&groupOrder=%5B%22Primary%22%2C%22Metastasis%22%5D) + ## Oct 12, 2022 @@ -74,7 +156,8 @@ * [Urothelial Carcinoma (BCAN/HCRN 2022)](http://www.cbioportal.org/study/summary?id=blca_bcan_hcrn_2022) *203 samples* ## Sep 6, 2022 -* **Enhancement**: Oncoprint can now save clinical tracks after login +* **Enhancement**: Oncoprint can now save clinical tracks after login: + ## Aug 11, 2022 @@ -90,15 +173,30 @@ * [Pan-cancer Analysis of Advanced and Metastatic Tumors (BCGSC, Nature Cancer 2020)](https://www.cbioportal.org/study/summary?id=pog570_bcgsc_2020) *570 samples* * [Prostate Adenocarcinoma (MSK, Clin Cancer Res. 2022)](https://www.cbioportal.org/study/summary?id=prad_pik3r1_msk_2021) *1,417 samples* +## Jun 7, 2022 +* **New Feature**: Add heatmap to plot options on _Comparison Page_. [Example: Primary vs Metastatic Prostate Cancer in MSK-IMPACT (2017)](https://www.cbioportal.org/comparison/clinical?sessionId=5cf89323e4b0ab413787436c) + + + ## May 31, 2022 * **New Feature**: Added Quartiles, Median split and Generate bins options for bar charts on the study view page, where Generate bins allows user to define bin size and min value - + + + ## May 12, 2022 * **New Feature**: Show cohort alteration frequencies in pathways from [NDEx](https://www.ndexbio.org/iquery/) on the _Results View_. [Example: Glioblastoma signaling pathways in MSK-IMPACT (2017) cohort](https://bit.ly/3sE4UqD) +## May 24, 2022 +* **New Feature**: Add Help buttons on various pages and tabs, including the homepage + +## May 10, 2022 +* **New Feature**: Use IGV for the genomic overview on the _Patient View_. [Example: Endometrial cancer patient in TCGA](https://www.cbioportal.org/patient?studyId=ucec_tcga_pub&caseId=TCGA-BK-A0CC) + + + ## May 5, 2022 * **New Feature**: View mutations and copy number changes in the [Integrative Genomics Viewer (IGV)](https://igv.org/) on the _Patient View_. [Example: Endometrial cancer patient in TCGA](https://www.cbioportal.org/patient?studyId=ucec_tcga_pub&caseId=TCGA-BK-A0CC) @@ -116,7 +214,7 @@ ## Apr 20, 2022 * **Added data** consisting of 2,557 samples from 5 studies: - * [Breast Cancer (HTAN, 2022)](https://www.cbioportal.org/study/summary?id=brca_hta9_htan_2022) *5 samples* + * [Breast Cancer (HTAN OHSU, 2022)](https://www.cbioportal.org/study/summary?id=brca_hta9_htan_2022) *5 samples* * [Colorectal Cancer (MSK, 2022)](https://www.cbioportal.org/study/summary?id=crc_dd_2022) *47 samples* * [Pediatric Pancan Tumors (MSK, 2022)](https://www.cbioportal.org/study/summary?id=mixed_kunga_msk_2022) *135 samples* * [Sarcoma (MSK, 2022)](https://www.cbioportal.org/study/summary?id=sarcoma_mskcc_2022) *2,138 samples* @@ -128,6 +226,32 @@ * Pan-can studies methylation addition: methylation profile (27k and 450k merged) are added to all 32 TCGA Pan-Can studies, in generic assay format. Data source: [GDC](https://gdc.cancer.gov/node/977). Example: search by gene or probe from dropdown, to add a chart in study view, a track in Oncoprint (single study query only), or plots in plots tab. Screen Shot 2022-03-22 at 9 52 20 PMScreen Shot 2022-03-22 at 9 52 27 PMScreen Shot 2022-03-22 at 9 53 38 PM * Single cell (type fraction and phases) data (in generic assay format) is added to [Glioblastoma (CPTAC, Cell 2021)](https://www.cbioportal.org/study/summary?id=gbm_cptac_2021) +* **New Feature** For the new HTAN OHSU study there is now also an integration with [Harvard LSP](https://labsyspharm.org/)'s [Minerva](https://www.cycif.org/software/minerva) for exploring multiplex imaging: + + + + +## Mar 1, 2022 +* **New Documentation**: + * Add a [User Guide](https://docs.cbioportal.org/user-guide/) + * Add [Study View and Query How-to videos](https://docs.cbioportal.org/user-guide/overview/#how-to-videos) + +## Feb 8, 2022 +* **New Feature**: Create X vs Y violin plots in _Study View_ using any categorical and numerical clinical data: + + + +## Jan 19, 2022 +* **New Feature**: Numerical filters on the _Study View_ are now editable: + + +* **New Feature**: In the annotation column choose between showing a single icon OncoKB icon or multiple (one for therapeutic, diagnostic and prognostic): + + + +## Jan 10, 2022 +* **New Documentation for Local cBioPortal Installations**: + * Explain how to use [Genome Nexus to annotate MAF files](https://docs.cbioportal.org/file-formats/#create-the-cbioportal-mutation-data-file-with-genome-nexus-with-a-minimal-maf-file) ## Jan 4, 2022 * **Added data** consisting of 27,447 samples from 10 studies: @@ -142,6 +266,7 @@ * [MSK MetTropism (MSK, Cell 2021)](https://www.cbioportal.org/study/summary?id=msk_met_2021) *25,775 samples* * [Cancer Therapy and Clonal Hematopoiesis (MSK, 2021)](https://www.cbioportal.org/study/summary?id=msk_ch_ped_2021) *657 samples* + * **Added TMB (nonsynonymous) scores** for all studies. [Example: new TMB field for study gbm_cptac_2021](https://www.cbioportal.org/study/clinicalData?id=gbm_cptac_2021) (Details for the calculation can be found [HERE](https://github.com/cBioPortal/datahub-study-curation-tools/blob/master/tmb/calculate_tmb/Readme.md)) Screen Shot 2022-01-04 at 11 39 20 PM @@ -282,6 +407,7 @@ * **New Feature**: Display and compare generic assays, such as microbiome and treatment response, on the study view [Example: Prasinovirus microbiome signatures in TCGA](https://www.cbioportal.org/study?id=6000b6aae4b015b63e9d4d44) + * **New Feature**: The Plots tab on _Results View_ now allows you to group alterations by Driver and VUS [Example: POLE driver mutations vs VUSs against mutation counts in TCGA Colorectal Adenocarcinoma](https://bit.ly/3ssY9Gu) diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index ed759c38b23..5411d990a09 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -6,7 +6,7 @@ * [User Guide](user-guide/README.md) * [New Users](user-guide/new-users.md) * [Frequently Asked Questions](user-guide/faq.md) - * [Overview of Resources](user-guide/overview.md) + * [Tutorials](user-guide/overview.md) * [Page Specific Resources](user-guide/by-page.md) * [OQL](user-guide/oql.md) * [News](News.md) @@ -33,8 +33,9 @@ * [Authenticating and Authorizing Users via Keycloak](deployment/authorization-and-authentication/Authenticating-and-Authorizing-Users-via-keycloak.md) * [Authenticating Users via Tokens](deployment/authorization-and-authentication/Authenticating-Users-via-Tokens.md) * [Customization]() - * [Customizing your cBioPortal Instance via portal.properties](deployment/customization/Customizing-your-instance-of-cBioPortal.md) - * [More portal.properties Settings](deployment/customization/portal.properties-Reference.md) + * [Customizing your cBioPortal Instance via application.properties](deployment/customization/Customizing-your-instance-of-cBioPortal.md) + * [More application.properties Settings](deployment/customization/application.properties-Reference.md) + * [Security Properties Settings](deployment/customization/security.properties-Reference.md) * [Configuring Caching Behavior](deployment/customization/Caching.md) * [How does the study view organize the charts](deployment/customization/Studyview.md) * [Utilize priority setting from database to visualize charts](deployment/customization/Studyview.md) diff --git a/docs/Support-multiple-reference-genomes.md.BK b/docs/Support-multiple-reference-genomes.md.BK index 37f8ef56593..2f2f36e30f4 100644 --- a/docs/Support-multiple-reference-genomes.md.BK +++ b/docs/Support-multiple-reference-genomes.md.BK @@ -11,7 +11,7 @@ and migrate your database schema to the latest version. The migrartion script by if your study is profiled by a reference geome other than a default genome value listed in your portal properties file. **Important Note** -* Add the following default values to your portal.properties file. Those default genome values will be used by the validation script when importing a new study. +* Add the following default values to your application.properties file. Those default genome values will be used by the validation script when importing a new study. ```# species and genomic information species=human ncbi.build=GRCh37 diff --git a/docs/Updating-gene-and-gene_alias-tables.md b/docs/Updating-gene-and-gene_alias-tables.md index 0b6f7c9a0d9..46e00489248 100644 --- a/docs/Updating-gene-and-gene_alias-tables.md +++ b/docs/Updating-gene-and-gene_alias-tables.md @@ -41,7 +41,7 @@ ALTER TABLE `geneset` AUTO_INCREMENT = 1; ``` 4- Restart cBioPortal (restart webserver) or call the `/api/cache` endpoint with a `DELETE` http-request -(see [here](/deployment/customization/portal.properties-Reference.md#evict-caches-with-the-apicache-endpoint) for more information) +(see [here](/deployment/customization/application.properties-Reference.md#evict-caches-with-the-apicache-endpoint) for more information) to clean-up any cached gene lists. 5- To import gene data type the following commands when in the folder `/core/src/main/scripts`: diff --git a/docs/Updating-your-cBioPortal-installation.md b/docs/Updating-your-cBioPortal-installation.md index 011c7a39fa5..6f4d4abc515 100644 --- a/docs/Updating-your-cBioPortal-installation.md +++ b/docs/Updating-your-cBioPortal-installation.md @@ -12,11 +12,11 @@ DB schema version expected by Portal: yyy ``` where `xxx` and `yyy` will be different version numbers. -If you get `DB version expected by Portal: 0` (i.e. you are building the new release from source), you need to add a new property to your `portal.properties` file which is needed for this check. +If you get `DB version expected by Portal: 0` (i.e. you are building the new release from source), you need to add a new property to your `application.properties` file which is needed for this check. #### Step1 -In your `portal.properties` file (e.g. `/src/main/resources/portal.properties`) add the following property: +In your `application.properties` file (e.g. `/src/main/resources/application.properties`) add the following property: ``` # this is the *expected* DB version (expected by the code). Don't set it manually, it is filled by maven: db.version=${db.version} @@ -28,7 +28,7 @@ Compile your code again. After restarting the webserver the page should now stat ## Running the migration script -First, make sure you have the DB connection properties correctly set in your portal.properties file (see [DB connection settings here](/deployment/customization/portal.properties-Reference.md#database-settings)). +First, make sure you have the DB connection properties correctly set in your application.properties file (see [DB connection settings here](/deployment/customization/application.properties-Reference.md#database-settings)). **Dependencies:** the migration script is a Python script that depends on the `mysqlclient` library. If necessary, you can install it with the following commands (example for Ubuntu): ```console @@ -70,4 +70,4 @@ etc ``` **Final step:** Restart your webserver or call the `/api/cache` endpoint with a `DELETE` http-request -(see [here](/deployment/customization/portal.properties-Reference.md#evict-caches-with-the-apicache-endpoint) for more information). +(see [here](/deployment/customization/application.properties-Reference.md#evict-caches-with-the-apicache-endpoint) for more information). diff --git a/docs/Using-the-dataset-validator.md b/docs/Using-the-dataset-validator.md index d44ff0d2505..70468db1fd4 100644 --- a/docs/Using-the-dataset-validator.md +++ b/docs/Using-the-dataset-validator.md @@ -776,7 +776,7 @@ cBioPortal is gradually introducing support for mouse. If you want to load mouse As an example, the command for the mouse example using the three parameters is given: ``` -./validateData.py -s ../../../test/scripts/test_data/study_es_0/ -P ../../../../../src/main/resources/portal.properties -u http://localhost:8080 -v +./validateData.py -s ../../../test/scripts/test_data/study_es_0/ -P ../../../../../src/main/resources/application.properties -u http://localhost:8080 -v ``` ## Running the validator for multiple studies diff --git a/docs/deployment/authorization-and-authentication/Authenticating-Users-via-SAML.md b/docs/deployment/authorization-and-authentication/Authenticating-Users-via-SAML.md index ebcab3d5e51..45d53189b54 100644 --- a/docs/deployment/authorization-and-authentication/Authenticating-Users-via-SAML.md +++ b/docs/deployment/authorization-and-authentication/Authenticating-Users-via-SAML.md @@ -121,7 +121,7 @@ both keystore and secure-key. This seems to be an extra restriction by Tomcat. ## Modifying configuration -Within portal.properties, make sure that: +Within application.properties, make sure that: app.name=cbioportal @@ -197,7 +197,7 @@ Next, please read the Wiki page on [User Authorization](User-Authorization.md), ## Configuring the Login.html Page (not applicable to most external IDPs) -The login page is configurable via the `portal.properties` properties `skin.authorization_message` and `skin.login.saml.registration_htm`. +The login page is configurable via the `application.properties` properties `skin.authorization_message` and `skin.login.saml.registration_htm`. For example in `skin.authorization_message` you can be set to something like this: ``` diff --git a/docs/deployment/authorization-and-authentication/Authenticating-Users-via-Tokens.md b/docs/deployment/authorization-and-authentication/Authenticating-Users-via-Tokens.md index f5952fb122b..36d0899ca9f 100644 --- a/docs/deployment/authorization-and-authentication/Authenticating-Users-via-Tokens.md +++ b/docs/deployment/authorization-and-authentication/Authenticating-Users-via-Tokens.md @@ -37,7 +37,7 @@ A step-by-step guide to configure KeyCloak to provide OAuth2 client functionalit ### Modifying Configuration -The following properties must be present in portal.properties in order to allow direct access to the cBioPortal web service when login is required: +The following properties must be present in application.properties in order to allow direct access to the cBioPortal web service when login is required: **Property**: dat.method (required) diff --git a/docs/deployment/authorization-and-authentication/Authenticating-and-Authorizing-Users-via-keycloak.md b/docs/deployment/authorization-and-authentication/Authenticating-and-Authorizing-Users-via-keycloak.md index 1a9271c4bcc..977fac3d971 100644 --- a/docs/deployment/authorization-and-authentication/Authenticating-and-Authorizing-Users-via-keycloak.md +++ b/docs/deployment/authorization-and-authentication/Authenticating-and-Authorizing-Users-via-keycloak.md @@ -129,7 +129,7 @@ should now see the certificate and no private key. ## Modifying configuration -1. Within the portal.properties file , make sure that this line is present: +1. Within the application.properties file , make sure that this line is present: ``` app.name=cbioportal ``` @@ -314,7 +314,7 @@ The step below were verified to work with Keycloak versions 4.8.3.Final and 8.0. #### Credentials tab -Select `Client Id and Secret`. Take notice of the value of _Secret_ the secret field. This secret should be added to `portal.properties` file of the cBioPortal backend. +Select `Client Id and Secret`. Take notice of the value of _Secret_ the secret field. This secret should be added to `application.properties` file of the cBioPortal backend. | parameter | value | comment | | ------------- |:-------------:| -----:| @@ -352,7 +352,7 @@ Enable _Full Scope_. This setting will include the user roles defined in the `cb ![](/images/previews/oauth2_client_5.png) -3. Add these parameters to `portal.properties` of the cBioPortal backend. +3. Add these parameters to `application.properties` of the cBioPortal backend. | parameter | value | comment | | ------------- |:-------------:| -----:| @@ -380,7 +380,7 @@ Then, rebuild the WAR, redeploy, and try to authenticate again. Your log file w If you're using the Docker container, mount the file instead with `-v ./logback.xml:/cbioportal-webapp/WEB-INF/classes/logback.xml`. #### Determining jwtRolesPath for OAuth2 Token -By default user-roles are extracted from path `resource_access::cbioportal::roles` in the JWT json. Changes to the configuration of roles at the realm and client level in Keycloak instance can alter this path and must be set acordingly with the `dat.oauth2.jwtRolesPath` property in the `portal.properties` file. +By default user-roles are extracted from path `resource_access::cbioportal::roles` in the JWT json. Changes to the configuration of roles at the realm and client level in Keycloak instance can alter this path and must be set acordingly with the `dat.oauth2.jwtRolesPath` property in the `application.properties` file. To check the the roles path, go into the `Client Scopes` tab inside KeyCloak. Enter the `Evaluate` section, select a test user, and click `Evaluate`. In the section below, select the `Generated Access Token` tab to examine the JWT structure. @@ -405,5 +405,5 @@ A sample JWT might look like this: "scope": "openid" } ``` -The `jwtRolesPath` in this case would be `realm_access::roles`. Double check this against the `jwtRolesPath` value set in `portal.properties`. +The `jwtRolesPath` in this case would be `realm_access::roles`. Double check this against the `jwtRolesPath` value set in `application.properties`. diff --git a/docs/deployment/authorization-and-authentication/User-Authorization.md b/docs/deployment/authorization-and-authentication/User-Authorization.md index 773fab95211..451dfbec6ca 100644 --- a/docs/deployment/authorization-and-authentication/User-Authorization.md +++ b/docs/deployment/authorization-and-authentication/User-Authorization.md @@ -73,7 +73,7 @@ The value in the EMAIL column should be the same email address contained in the The value in the AUTHORITY column is made of two parts: -* The first part is the name of your portal instance. This name should also match the `app.name` property found in the `portal.properties` file. +* The first part is the name of your portal instance. This name should also match the `app.name` property found in the `application.properties` file. * Following a colon delimiter, the second part is the [cancer_study_identifier](../../File-Formats.md#cancer-study) of the cancer study this user has rights to access. **If the user has rights to all available cancer studies, a single entry with the keyword `app.name:` + "ALL" is sufficient (so e.g. "cbioportal:ALL").** @@ -135,7 +135,7 @@ After **next login**, the user 'john.smith@gmail.com' will have access to these ## Configuring PUBLIC studies -To enable a set of public studies that should be visible to all users, without the need to configure this for each user in the `authorities` and `users` tables, you can set the property `always_show_study_group` in **portal.properties** file. For example, you can set: +To enable a set of public studies that should be visible to all users, without the need to configure this for each user in the `authorities` and `users` tables, you can set the property `always_show_study_group` in **application.properties** file. For example, you can set: ``` always_show_study_group=PUBLIC diff --git a/docs/deployment/customization/Caching.md b/docs/deployment/customization/Caching.md index e4b657673c7..8368a8c5780 100644 --- a/docs/deployment/customization/Caching.md +++ b/docs/deployment/customization/Caching.md @@ -10,8 +10,8 @@ if they have already been constructed. They would only be constructed for the in The portal is configured to use Ehcache or Redis for backend caching. Ehcache supports a hybrid (disk + heap), disk-only, and heap-only mode. Redis stores the cache in memory and periodically writes the updated data to disk. Cache -configuration is specified inside `portal.properties`(more -information [here](/deployment/customization/portal.properties-Reference.md#cache-settings)). +configuration is specified inside `application.properties`(more +information [here](/deployment/customization/application.properties-Reference.md#cache-settings)). ## Creating additional caches @@ -100,7 +100,7 @@ be cached. Those might look like this example: public String getDataFromClinicalDataRepository(String param) {} ``` -Additionally, new properties for setting cache sizes should be added to `portal.properties` and loaded into +Additionally, new properties for setting cache sizes should be added to `application.properties` and loaded into the [CustomEhcachingProvider](https://github.com/cBioPortal/cbioportal/blob/master/persistence/persistence-api/src/main/java/org/cbioportal/persistence/util/CustomEhcachingProvider.java) . Alternatively, values may be hardcoded directly inside [CustomEhcachingProvider](https://github.com/cBioPortal/cbioportal/blob/master/persistence/persistence-api/src/main/java/org/cbioportal/persistence/util/CustomEhcachingProvider.java) @@ -122,7 +122,7 @@ whether a user has access to the data of a particular sample list or molecular p By default, the user-authorization cache is implemented as a HashMap that is populated when cBioPortal is started. This implementation allows for very fast response times of user-permission evaluation. -The user-authorization cache can be delegated to the Spring-managed caching solution by setting the [cache.cache-map-utils.spring-managed](portal.properties-Reference.md#cache-settings) +The user-authorization cache can be delegated to the Spring-managed caching solution by setting the [cache.cache-map-utils.spring-managed](application.properties-Reference.md#cache-settings) to _true_. Depending on the implementation, this may add a delay to any data request that is caused by the additional consultation of the external cache. This configuration should only be used where a central caching solution is required or no instance/container-specific local caches are allowed. For example, cache eviction via the `api/cache` endpoint in a Kubernetes @@ -142,7 +142,7 @@ eviction end point is that user-sessions remain undisturbed since the portal ins cache eviction enpoint is disabled and can be enabled by setting `cache.endpoint.enabled` to _true_. The endpoint is secured by a secret API key that can be customized with the `cache.endpoint.api-key` property. Caches are evicted by making a DELETE request to the endoint while passing the API key in the `X-API-KEY` header. When using _curl_ use the -following command (replace the API key for the value configured in _portal.properties_): +following command (replace the API key for the value configured in _application.properties_): ``` curl -X DELETE http://my-portal-url.org/api/cache -H 'X-API-KEY: fd15f1ae-66f2-4b8a-8d54-fb899b03557e' @@ -154,7 +154,7 @@ When a study is added, deleted or updated, a more selective cache eviction strat cached data is evicted. This more selective cache eviction is triggered by calling the `/api/cache/{studyId}` endpoint where _{studyId}_ is the _cancer_study_identifier_ stated in the meta-study.txt file. When using _curl_ use the following command after update of a study with study identifier _my_cancer_study_ (replace the API key for the value -configured in _portal.properties_): +configured in _application.properties_): ``` curl -X DELETE http://my-portal-url.org/api/cache/my_cancer_study -H 'X-API-KEY: fd15f1ae-66f2-4b8a-8d54-fb899b03557e' diff --git a/docs/deployment/customization/Customizing-your-instance-of-cBioPortal.md b/docs/deployment/customization/Customizing-your-instance-of-cBioPortal.md index 51fbbc78f9f..0efd5c0254f 100644 --- a/docs/deployment/customization/Customizing-your-instance-of-cBioPortal.md +++ b/docs/deployment/customization/Customizing-your-instance-of-cBioPortal.md @@ -6,10 +6,10 @@ This page focuses on the skin properties, which allow you to customize the web page cosmetics, such as custom images, texts, which tabs are visible, etc. Nearly all the skins properties have defaults, which can be overwritten by -changing the `portal.properties` file located in `$PORTAL_HOME`--see +changing the `application.properties` file located in `$PORTAL_HOME`--see [the deployment manual](/deployment/deploy-without-docker/Deploying.md). If your cBioPortal instance -does not yet contain a `portal.properties` file, you can copy -`src/main/resources/portal.properties.EXAMPLE` and edit it. +does not yet contain a `application.properties` file, you can copy +`src/main/resources/application.properties.EXAMPLE` and edit it. Below you can find the complete list of all the available skin properties. @@ -278,19 +278,12 @@ If the download_group is present in user groups then download options are shown false true / false - + google_analytics_profile_id enables google analaytics tracking on your site disabled string - - - - - - - @@ -303,7 +296,7 @@ Creating you own local news/about or FAQ page involves three steps. For example, 1. Copy `/portal/src/main/webapp/content/news.html` to `news_XXXX.html` 2. Modify `news_XXXX.html` as needed. -3. Edit the `portal.properties` file and change the `skin.documentation.news` property, giving it the name of your news HTML component. +3. Edit the `application.properties` file and change the `skin.documentation.news` property, giving it the name of your news HTML component. You may need to modify additional settings depending on whether you're e.g. using markdown pages. Please refer to the [cBioPortal Documentation](#cbioportal-documentation-settings) for more information. diff --git a/docs/deployment/customization/portal.properties-Reference.md b/docs/deployment/customization/application.properties-Reference.md similarity index 95% rename from docs/deployment/customization/portal.properties-Reference.md rename to docs/deployment/customization/application.properties-Reference.md index aea31578dcc..f26ddac68bf 100644 --- a/docs/deployment/customization/portal.properties-Reference.md +++ b/docs/deployment/customization/application.properties-Reference.md @@ -1,6 +1,6 @@ -# More portal.properties Settings +# More application.properties Settings -This page describes the main properties within portal.properties. +This page describes the main properties within application.properties. ## Database Settings @@ -55,7 +55,7 @@ skin.show_about_tab= The cross cancer study query default is a list of studies used when querying one or more genes and not specifying a specific study or list of studies. There are two ways in which the default cross cancer study list is used: 1. When using the linkout links without a study e.g. `/ln?q=TP53:MUT`. Those links are used mostly used to allow for easy linking to particular queries. One can't get those links using the cBioPortal user interface itself, they are only mentioned in the documentation of the Web API (https://www.cbioportal.org/webAPI). -2. In the quick search when querying for a gene. Quick search is disabled by default. It is a beta feature. See the [quick search documentation](portal.properties-Reference.md#quick-search-beta). +2. In the quick search when querying for a gene. Quick search is disabled by default. It is a beta feature. See the [quick search documentation](application.properties-Reference.md#quick-search-beta). The configuration is set with the following if you have session service enabled: @@ -84,7 +84,7 @@ Enable or disable the quick search with the following: quick_search.enabled=true ``` -The default studies queried when searching for a single gene is defined with the `default_cross_cancer_study_session_id` or `default_cross_cancer_study_list` properties as described in the [cross cancer study query default section](portal.properties-Reference.md#cross-cancer-study-query-default). +The default studies queried when searching for a single gene is defined with the `default_cross_cancer_study_session_id` or `default_cross_cancer_study_list` properties as described in the [cross cancer study query default section](application.properties-Reference.md#cross-cancer-study-query-default). ### Hide sections in the right navigation bar @@ -226,6 +226,15 @@ skin.patient_view.copy_number_table.columns.show_on_init= skin.patient_view.structural_variant_table.columns.show_on_init= ``` +### Default sort columns on Mutation, Copy-Number and Structural Variant Tables + +Define the column that are going to sort be default in the Mutation, Copy-Number and Structural Variant Tables on the Patient View and the Mutation Table in the Results View. +Column name should be exactly the same as shown in tables. +``` +skin.results_view.tables.default_sort_column= +skin.patient_view.tables.default_sort_column= +``` + ### Define custom sample type colors Define the colors of custom sample types in the patient view using a json object with for each sample type a color: ``` @@ -335,7 +344,7 @@ google_analytics_profile_id ## Password Authentication -The portal supports password authentication via Google+. Before you start you need to setup a google account that will own the authentication API. Follow https://developers.google.com/identity/sign-in/web/devconsole-project to get clientID and secret. Fill it in portal.properties: +The portal supports password authentication via Google+. Before you start you need to setup a google account that will own the authentication API. Follow https://developers.google.com/identity/sign-in/web/devconsole-project to get clientID and secret. Fill it in application.properties: ``` googleplus.consumer.key=195047654890-499gl89hj65j8d2eorqe0jvjnfaxcln0.apps.googleusercontent.com @@ -346,7 +355,7 @@ googleplus.consumer.secret=2jCfg4SPWdGfXF44WC588dK To activate password authentication follow the [Deployment with authentication steps](/deployment/deploy-without-docker/Deploying.md#required-login) and set `authenticate=googleplus`. -In addition, set this property in `portal.properties`: +In addition, set this property in `application.properties`: ``` app.name=cbioportal @@ -459,11 +468,13 @@ These data formats are described in the [cBioPortal MAF specifications](/File-Fo **Enabling custom annotations in the OncoPrint** -To enable functionality for one or both types of custom annotations, enter values for the following properties. These labels will appear in the OncoPrint's "Mutation color" menu. +To enable functionality for one or both types of custom annotations, enter values for the following properties. These values will appear in the OncoPrint's "Mutation color" menu, Patient View's (mutation, CNA, SV) tables, Results View's mutation table, and Group Comparison View's mutation table. ``` -oncoprint.custom_driver_annotation.binary.menu_label=Custom driver annotation -oncoprint.custom_driver_annotation.tiers.menu_label=Custom driver tiers +oncoprint.custom_driver_annotation.binary.menu_label=Custom Driver +oncoprint.custom_driver_annotation.binary.menu_description=Custom driver tiers +oncoprint.custom_driver_annotation.tiers.menu_label=Custom Driver Tiers +oncoprint.custom_driver_annotation.tiers.menu_description=Custom driver tiers ``` **Automatic selection of OncoKB, hotspots and custom annotations** @@ -547,7 +558,7 @@ This gene set will add the following in the query box: ## Cache Settings -cBioPortal is supported on the backend with Ehcache or Redis. These caches are configurable from within portal.properties through the following properties. +cBioPortal is supported on the backend with Ehcache or Redis. These caches are configurable from within application.properties through the following properties. The cache type is set using `persistence.cache_type`. Valid values are `no-cache`, `redis` (redis), `ehache-heap` (ehcache heap-only), `ehache-disk` (ehcache disk-only), and `ehache-hybrid` (ehcache disk + heap). By default, `persistence.cache_type` is set to `no-cache` which disables the cache. When the cache is disabled, no responses will be stored in the cache. @@ -778,4 +789,12 @@ By default, the studies loaded into a local cBioPortal instance are organized ba ``` priority_studies= ``` -The value of this variable will create a custom category with studies on the top of the study selector view. The format for the string should be category1#study1a,study1b,study1c;category2#study2 (e.g., PanCancer Studies#msk_impact_2017), where the ``category`` can be any string and the ``study`` should be the study ID of the required uploaded study. \ No newline at end of file +The value of this variable will create a custom category with studies on the top of the study selector view. The format for the string should be category1#study1a,study1b,study1c;category2#study2 (e.g., PanCancer Studies#msk_impact_2017), where the ``category`` can be any string and the ``study`` should be the study ID of the required uploaded study. + +## Study Tag functionality +Study Tags allow portal maintainers to define miscellaneous descriptive meta data to studies, which will be shown to users in tooltips and are also searchable. This feature +is on by default but can be disabled using the following property. +``` +//boolean +enable_study_tags=true|false +``` diff --git a/docs/deployment/customization/portal.properties--Reference.md b/docs/deployment/customization/portal.properties--Reference.md new file mode 100644 index 00000000000..b9b41085a55 --- /dev/null +++ b/docs/deployment/customization/portal.properties--Reference.md @@ -0,0 +1 @@ +This file has been depreciated and information about customizing cBioPortal can be found in [application.properties documentation](/deployment/customization/application.properties-Reference.md). \ No newline at end of file diff --git a/docs/deployment/customization/security.properties-Reference.md b/docs/deployment/customization/security.properties-Reference.md index 1eede866e94..c63b828ed23 100644 --- a/docs/deployment/customization/security.properties-Reference.md +++ b/docs/deployment/customization/security.properties-Reference.md @@ -11,12 +11,32 @@ The following are the properties for configuring authentication and authorizatio authenticate=false ``` ### OAUTH2 +#### NOTE for Custom Authorization (validate users via db) +```properties +authenticate=oauth2 +authorization=true +``` #### Google OAuth2 Client/Login Configuration #### Example of utilizing google client for oAuth2 (Authentication) ```properties spring.security.oauth2.client.registration.google.clientId= spring.security.oauth2.client.registration.google.clientSecret= +spring.security.oauth2.client.provider.google.user-name-attribute=email +``` + +### Microsoft OAUTH2 Multi-tenant Client/Login Config +#### Example with Utilizing AzureAD for oAuth2 +```properties +spring.security.oauth2.client.registration.azure.authorization-grant-type=authorization_code +spring.security.oauth2.client.registration.azure.client-id= +spring.security.oauth2.client.registration.azure.clientSecret= +spring.security.oauth2.client.provider.azure.user-name-attribute=email +spring.security.oauth2.client.registration.azure.redirect-uri=http://localhost:8080/login/oauth2/code/azure +spring.security.oauth2.client.provider.azure.authorization-uri=https://login.microsoftonline.com/common/oauth2/v2.0/authorize +spring.security.oauth2.client.provider.azure.token-uri=https://login.microsoftonline.com/common/oauth2/v2.0/token +spring.security.oauth2.client.provider.azure.jwk-set-uri=https://login.microsoftonline.com/common/discovery/v2.0/keys +spring.security.oauth2.client.registration.azure.scope=openid,profile,email ``` #### Custom OAUTH2 Client Configuration @@ -46,6 +66,10 @@ spring.security.oauth2.client.registration.cbio-idp.client-secret= ``` ### SAML Configuration +#### Example to generate cert and key +```shell +openssl req -newkey rsa:2048 -nodes -keyout local.key -x509 -days 365 -out local.crt +``` ```properties @@ -86,6 +110,8 @@ dat.oauth2.accessTokenUri=/.../token dat.oauth2.userAuthorizationUri=/.../auth dat.oauth2.jwkUrl=/.../certs dat.oauth2.redirectUri=/.../api/data-access-token/oauth2 +spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8081/realms/cbioportal + ``` ### Authorization Configuration/Study View Settings @@ -100,4 +126,12 @@ always_show_study_group=PUBLIC filter_groups_by_appname=false # Can disable authorization security.method_authorization_enabled=true +``` + +### CORS Configuration +To Enable CORS set the allowed-origins urls. (comma delimited list) +To enable all origins use * +```properties +security.cors.allowed-origins=* +##Or http://localhost:8080,http://localhost:8081 ``` \ No newline at end of file diff --git a/docs/deployment/deploy-without-docker/Build-from-Source.md b/docs/deployment/deploy-without-docker/Build-from-Source.md index 82b5529ffde..52625640bd1 100644 --- a/docs/deployment/deploy-without-docker/Build-from-Source.md +++ b/docs/deployment/deploy-without-docker/Build-from-Source.md @@ -2,37 +2,10 @@ ## Building with Maven -While building, you must point the environment variable `PORTAL_HOME` to -the root directory containing the portal source code. - -For example, run a command like the following if on macOS: -``` -export PORTAL_HOME=/Users/ecerami/dev/cbioportal -``` - -To compile the cBioPortal source code, move into the source directory and -run the following maven command: +To compile the cBioPortal source code, move into the root directory and run the following maven command: ``` mvn -DskipTests clean install ``` -After this command completes, you will find a `cbioportal.war` file suitable -for Apache Tomcat deployment in `portal/target/`. It is not neccessary to -install Tomcat yourself, since a command line runnable version of Tomcat is -provided as a dependency in `portal/target/dependency/webapp-runner.jar`. - -However, if you will be deploying to a standalone Tomcat installation, and -if you have configured Tomcat to use the Redisson client for user session -management, you should expect a clash between the Redisson client being -used for session management and the Redisson client which is embedded in -the cbioportal.war file for the optional "redis" persitence layer caching -mode. In this case, you should avoid using the "redis" option for the portal -property `persistence.cache_type` and you should prevent the Redisson -client from being packaged in cbioportal.war by building with this command -instead: - -##### alternative for standalone tomcat deployments which use redis session management -``` -mvn -Dexclude-redisson -DskipTests clean install -``` +Note: cBioPortal 6.X requires Java 21 diff --git a/docs/deployment/deploy-without-docker/Deploying.md b/docs/deployment/deploy-without-docker/Deploying.md index 246a9952705..ad4363f9c45 100644 --- a/docs/deployment/deploy-without-docker/Deploying.md +++ b/docs/deployment/deploy-without-docker/Deploying.md @@ -1,131 +1,45 @@ # Deploying the Web Application -## Prepare the global configuration file +## Before running cbioportal backend -The portal is configured using a global configuration file, `portal.properties`. An example file is available in the `src/main/resources` folder. Use it as a template to create your own: +You will need to update the src/main/resources/applications.properties to include your DB connection information. -``` -cd src/main/resources -cp portal.properties.EXAMPLE $HOME/cbioportal/portal.properties -``` - -For more information about the `portal.properties` file, see the [reference](/deployment/customization/Customizing-your-instance-of-cBioPortal.md) page. +The configuration defined in `application.properties` can also be passed as command line arguments. The priority of property loading is as follows: -Several scripts of cBioPortal use this `portal.properties` file to get info like db connection parameters. You can indicate the folder where this file is with an environment variable: - -``` -export PORTAL_HOME=$HOME/cbioportal -``` +1. `-D` command line parameters overrides all +2. `src/main/resources/application.properties` +3. `application.properties` supplied at compile time +4. Defaults defined in code -if your properties file is at `PORTAL_HOME/portal.properties` +Note that the `authenticate` property is currently required to be set as a command line argument, it won't work when set in `application.properties` (See issue [#6109](https://github.com/cBioPortal/cbioportal/issues/6109)). -## Run cBioPortal Session Service +Some scripts require a `${PORTAL_HOME}/application.properties` file, so it is best to define the properties there. -The cBioPortal app requires [session service](/Architecture-Overview.md#session-service). For instructions on how to run this without Docker see https://github.com/cBioPortal/session-service#run-without-docker. Once this is working, update the properties file: +For more information about the `application.properties` file, see the [reference](/deployment/customization/Customizing-your-instance-of-cBioPortal.md) page. -```bash -# session-service url: http://[host]:[port]/[session_service_app]/api/sessions/[portal_instance]/ -# example session-service url: http://localhost:8080/session_service/api/sessions/public_portal/ -# see: https://github.com/cBioPortal/session-service -session.service.url= -``` ## Run the cbioportal backend -To run the app we use `webapp-runner`. It's a command line version of Tomcat provided by [Heroku](https://github.com/jsimone/webapp-runner). All parameters can be seen with: +To run the backend execute the following commabd ``` -java -jar portal/target/dependency/webapp-runner.jar --help +java -jar target/cbioportal-exec.jar ``` -This runs the app in the foreground. If a port is already in use it will raise an error mentioning that. To change the port use the `--port` flag. +This runs the app in the foreground. If a port is already in use it will raise an error mentioning that. To change the port use the `--server.port` flag. -There are three main ways to run the portal: without authentication, with optional login and with required login. All of them require the cBioPortal session service to be running. -### Without authentication -In this mode users are able to use the portal, but they won't be able to save their own virtual studies and groups. See the [optional login section](#optional-login) to enable this. - -```bash -java \ - -jar \ - -Dauthenticate=noauthsessionservice \ - portal/target/dependency/webapp-runner.jar \ - portal/target/cbioportal.war -``` - -### Optional login - -In this mode users can see all the data in the portal, but to save their own groups and virtual studies they are required to log in. This will allow them to store user data in the session service. See the [tutorials](https://www.cbioportal.org/tutorials) section to read more about these features. - -```bash -java \ - -jar \ - -Dauthenticate=social_auth_google,social_auth_microsoft \ - portal/target/dependency/webapp-runner.jar \ - portal/target/cbioportal.war -``` - -Google and Microsoft live are supported as optional login currently. Possible values for authenticate are - -```bash --Dauthenticate=social_auth_google,social_auth_microsoft --Dauthenticate=social_auth_google --Dauthenticate=social_auth_microsoft -``` +There are three main ways to run the portal: without authentication, with optional login, and with required login. All of them require the cBioPortal session service to be running. -One needs to set the Google/Microsoft related configurations in the `portal.properties` file: +### Without authentication -``` -#For Google -googleplus.consumer.key= -googleplus.consumer.secret= +In this mode users are able to use the portal, but they won't be able to save their own virtual studies and groups. -#For Microsoft -microsoftlive.consumer.key= -microsoftlive.consumer.secret= ``` - -See [Google's Sign in Documentation](https://developers.google.com/identity/sign-in/web/sign-in#before\_you\_begin) to obtain these values. - -See [Microsoft Sign in Documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/scenario-web-app-sign-user-app-registration) to obtain these values. - -### Required login - -```bash -java \ - -Dauthenticate=CHOOSE_DESIRED_AUTHENTICATION_METHOD \ - -jar \ - portal/target/dependency/webapp-runner.jar \ - portal/target/cbioportal.war +java -jar target/cbioportal-exec.jar -Dauthenticate=false ``` -Change `CHOOSE_DESIRED_AUTHENTICATION_METHOD` to one of `googleplus`, `saml`, `openid`, `ad`, `ldap`. The various methods of authentication are described in the [Authorization and Authentication](/deployment/authorization-and-authentication) section. - -### Property configuration - -The configuration defined in `portal.properties` can also be passed as command line arguments. The priority of property loading is as follows: - -1. `-D` command line parameters overrides all -2. `${PORTAL_HOME}/portal.properties` -3. `portal.properties` supplied at compile time -4. Defaults defined in code - -Note that the `authenticate` property is currently required to be set as a command line argument, it won't work when set in `portal.properties` (See issue [#6109](https://github.com/cBioPortal/cbioportal/issues/6109)). - -Some scripts require a `${PORTAL_HOME}/portal.properties` file, so it is best to define the properties there. - -### Note for Tomcat Deployers - -Before we were using `webapp-runner`, our documentation recommended a system level installed Tomcat. In this case people might have been using `dbconnector=jndi` instead of the new default `dbconnector=dbcp`. There is a known issue where setting dbconnector in the properties file does not work ([#6148](https://github.com/cBioPortal/cbioportal/issues/6148)). It needs to be set as a command line argument. For Tomcat this means `CATALINA_OPT="-Ddbconnector=jndi"`. - -## Verify the Web Application - -Lastly, open a browser and go to:\ -[http://localhost:8080](http://localhost:8080) - -## Important +### With authentication -* Each time you modify any java code, you must recompile and redeploy the app. -* Each time you modify any properties (see customization options), you must restart the app -* Each time you add new data, you must restart the app or call the `/api/cache` endpoint with a `DELETE` http-request (see [here](/deployment/customization/portal.properties-Reference.md#evict-caches-with-the-apicache-endpoint) for more information). +To configure the authentication and authorization please consult the [Authorization](./../authorization-and-authentication/User-Authorization.md) and [Authentication](./../authorization-and-authentication/Authenticating-and-Authorizing-Users-via-keycloak.md) Sections. diff --git a/docs/deployment/deploy-without-docker/Import-the-Seed-Database.md b/docs/deployment/deploy-without-docker/Import-the-Seed-Database.md index 8e2453a34a6..fdab0c8463e 100644 --- a/docs/deployment/deploy-without-docker/Import-the-Seed-Database.md +++ b/docs/deployment/deploy-without-docker/Import-the-Seed-Database.md @@ -39,11 +39,12 @@ After download, the files can be unzipped by entering the following command: 4. (optional : support for microRNA genomic profiles) Import constructed gene table records for microRNA genomic profiles. Currently, cBioPortal supports the combined display of copy number alterations (generally reported for microRNA precursors) and expression (generally reported for microRNA mature forms) by adding gene table records which represent the combination of microRNA precursor and microRNA mature form. Appropriate aliases are added to the gene_alias table so that both the name of the precursor and the name of the mature form are recognized references to the combination. - After the code has been successfully configured and built, you can import the needed microRNA records by running the following command from the $PORTAL_HOME directory: +This involves downloading the cBioPortal Core code located [here](https://github.com/cBioPortal/cbioportal-core). + +After the code has been successfully configured and built, you can import the needed microRNA records by running the following command from the cBioPortal core directory: - ``` java -cp scripts/target/scripts-*.jar org.mskcc.cbio.portal.scripts.ImportGeneData -microrna core/src/main/resources/micrornas.tsv - ``` + **Important:** Please be aware of the version of the seed database. In the [README on datahub](https://github.com/cbioportal/datahub/blob/master/seedDB/README.md), we stated which version of cBioPortal is compatible with the current seed database. diff --git a/docs/deployment/deploy-without-docker/Load-Sample-Cancer-Study.md b/docs/deployment/deploy-without-docker/Load-Sample-Cancer-Study.md index b328c2953c3..37c653026de 100644 --- a/docs/deployment/deploy-without-docker/Load-Sample-Cancer-Study.md +++ b/docs/deployment/deploy-without-docker/Load-Sample-Cancer-Study.md @@ -4,13 +4,25 @@ Once you have confirmed that the cBioPortal server is installed, you are ready to import data. Importing a sample study is recommended to verify that everything is working correctly. -The cBioPortal distribution includes a [small dummy study, `study_es_0`](https://github.com/cBioPortal/cbioportal/tree/master/core/src/test/scripts/test_data/study_es_0), which contains all datatypes supported by cBioPortal. This document describes how to import the prerequisites for the sample study and how to import the study itself. +cBioPortal Core has a [small dummy study, `study_es_0`](https://https://github.com/cBioPortal/cbioportal-core/tree/main/src/test/scripts/test_data/study_es_0), which contains all datatypes supported by cBioPortal. This document describes how to import the prerequisites for the sample study and how to import the study itself. + + +## Download and Build cBioPortal Core + +``` + git clone https://github.com/cBioPortal/cbioportal-core.git + cd cbioportal-core + git checkout main + mvn -DskipTests clean install +``` + + ## Set the PORTAL_HOME environment variable Most cBioPortal command-line tools, including the data loading pipeline, expect the environment variable `$PORTAL_HOME` to point to a folder -containing the `portal.properties` configuration file, +containing the `application.properties` configuration file, as explained during [the previous step](./Deploying.md). Configure your shell to keep the variable set to the right folder. @@ -26,13 +38,13 @@ export PORTAL_HOME=/Users/johndoe/cbioportal The sample gene panel has to be imported before gene panel study data can be added to the database. ``` -cd /core/src/main/scripts +cd cbioportal-core/src/main/resources/scripts ./importGenePanel.pl --data ../../test/scripts/test_data/study_es_0/data_gene_panel_testpanel1.txt ./importGenePanel.pl --data ../../test/scripts/test_data/study_es_0/data_gene_panel_testpanel2.txt ``` After loading gene panels into the database, please restart Tomcat or call the `/api/cache` endpoint with a `DELETE` http-request -(see [here](/deployment/customization/portal.properties-Reference.md#evict-caches-with-the-apicache-endpoint) for more information) +(see [here](/deployment/customization/application.properties-Reference.md#evict-caches-with-the-apicache-endpoint) for more information) so that the validator can retrieve gene panel information from the cBioPortal API. More details to load your own gene panel and gene set data can be found here: [Import Gene Panels](/Import-Gene-Panels.md). @@ -44,7 +56,7 @@ First it's useful to validate the study `study_es_0`, to check if the data is fo To do so, go to the importer folder: ``` -cd /core/src/main/scripts/importer +cd cbioprtal-core/src/main/scripts/importer ``` and then run the following command: @@ -64,7 +76,7 @@ Validation of study succeeded with warnings. To import the sample study: ``` -cd /core/src/main/scripts/importer +cd cbioportal-core/src/main/scripts/importer ``` and then run the following command: @@ -81,4 +93,4 @@ Total time: 7742 ms ``` After loading the study data, please restart the app or call the `/api/cache` endpoint with a `DELETE` http-request -(see [here](/deployment/customization/portal.properties-Reference.md#evict-caches-with-the-apicache-endpoint) for more information). +(see [here](/deployment/customization/application.properties-Reference.md#evict-caches-with-the-apicache-endpoint) for more information). diff --git a/docs/deployment/deploy-without-docker/Pre-Build-Steps.md b/docs/deployment/deploy-without-docker/Pre-Build-Steps.md index b2a48bd78ca..dfb7cf2c7e9 100644 --- a/docs/deployment/deploy-without-docker/Pre-Build-Steps.md +++ b/docs/deployment/deploy-without-docker/Pre-Build-Steps.md @@ -5,6 +5,7 @@ Make sure that you have cloned the last code, and make sure you are on the `master` branch: ``` git clone https://github.com/cBioPortal/cbioportal.git + cd cbioportal git checkout master ``` @@ -23,6 +24,17 @@ log config, which you can then override easily. To modify the logging during tests the same EXAMPLE file can be copied to the relevant test resources folder. +## Prepare the global configuration file + +The portal is configured using a global configuration file, `application.properties`. An example file is available in the `src/main/resources` folder. Use it as a template to create your own: + +``` +cd src/main/resources +cp application.properties.EXAMPLE application.properties +``` + +For more information about the `application.properties` file, see the [reference](/deployment/customization/Customizing-your-instance-of-cBioPortal.md) page. + ## Create the cBioPortal MySQL Databases and User You must create a `cbioportal` database and a `cgds_test` database within MySQL, and a user account with rights to access both databases. This is done via the `mysql` shell. @@ -42,13 +54,13 @@ You must create a `cbioportal` database and a `cgds_test` database within MySQL, mysql> create database cgds_test; Query OK, 1 row affected (0.00 sec) - mysql> CREATE USER 'cbio_user'@'localhost' IDENTIFIED BY 'somepassword'; + mysql> CREATE USER 'cbio'@'localhost' IDENTIFIED BY 'P@ssword1'; Query OK, 0 rows affected (0.00 sec) - mysql> GRANT ALL ON cbioportal.* TO 'cbio_user'@'localhost'; + mysql> GRANT ALL ON cbioportal.* TO 'cbio'@'localhost'; Query OK, 0 rows affected (0.00 sec) - mysql> GRANT ALL ON cgds_test.* TO 'cbio_user'@'localhost'; + mysql> GRANT ALL ON cgds_test.* TO 'cbio'@'localhost'; Query OK, 0 rows affected (0.00 sec) mysql> flush privileges; diff --git a/docs/deployment/deploy-without-docker/Software-Requirements.md b/docs/deployment/deploy-without-docker/Software-Requirements.md index d6b2fed8815..813caad7366 100644 --- a/docs/deployment/deploy-without-docker/Software-Requirements.md +++ b/docs/deployment/deploy-without-docker/Software-Requirements.md @@ -16,13 +16,13 @@ The session service uses MongoDB 3.6.6 ## Java -As of this writing, the cBioPortal can be compiled and run from Java 11 and above. The software can be found and download from the [Oracle](https://www.oracle.com/us/technologies/java/overview/index.html) website. +cBioPortal requires Java 12 and above. The software can be found and download from the [Oracle](https://www.oracle.com/us/technologies/java/overview/index.html) website. On Ubuntu: ```sudo apt-get install default-jdk``` ## Apache Maven -The cBioPortal source code is an [Apache Maven](https://maven.apache.org/) driven project. The software needs to be downloaded and installed prior to building the application from source code. It can be found on the [Apache Maven](https://maven.apache.org/download.cgi) website. We are currently using version 3.5.4. +The cBioPortal source code is an [Apache Maven](https://maven.apache.org/) driven project. The software needs to be downloaded and installed prior to building the application from source code. It can be found on the [Apache Maven](https://maven.apache.org/download.cgi) website. We are currently using version 3.9.5. On Ubuntu: ```sudo apt-get install maven``` diff --git a/docs/deployment/docker/README.md b/docs/deployment/docker/README.md index 384b27423f4..c485500e9cf 100644 --- a/docs/deployment/docker/README.md +++ b/docs/deployment/docker/README.md @@ -108,17 +108,17 @@ or All public studies can be downloaded from https://www.cbioportal.org/datasets, or https://github.com/cBioPortal/datahub/. You can add any of them to the `./study` folder and import them. There's also a script (`./study/init.sh`) to download multiple studies. You can set `DATAHUB_STUDIES` to any public study id (e.g. `lgg_ucsf_2014`) and run `./init.sh`. ##### Notes on restarting -To avoid having to restart one can alternatively hit an API endpoint. To do so, call the `/api/cache` endpoint with a `DELETE` http-request (see [here](/deployment/customization/portal.properties-Reference.md#evict-caches-with-the-apicache-endpoint) for more information): +To avoid having to restart one can alternatively hit an API endpoint. To do so, call the `/api/cache` endpoint with a `DELETE` http-request (see [here](/deployment/customization/application.properties-Reference.md#evict-caches-with-the-apicache-endpoint) for more information): ``` curl -x DELETE -H "X-API-KEY: my-secret-api-key-value" http://localhost:8080/api/cache ``` -The value of the API key is configured in the _portal.properties_ file. You can visit http://localhost:8080 again and you should be able to see the new study. +The value of the API key is configured in the _application.properties_ file. You can visit http://localhost:8080 again and you should be able to see the new study. -#### Step 3 - Customize your portal.properties file ### +#### Step 3 - Customize your application.properties file ### -The properties file can be found in `./config/portal.properties`. Which was set up when running `init.sh`. +The properties file can be found in `./config/application.properties`. Which was set up when running `init.sh`. This properties file allows you to customize your instance of cBioPortal with e.g. custom logos, or point the cBioPortal container to e.g. use an external mysql database. See the [properties](/deployment/customization/Customizing-your-instance-of-cBioPortal.md) documentation for a comprehensive overview. diff --git a/docs/deployment/integration-with-other-webservices/OncoKB-Data-Access.md b/docs/deployment/integration-with-other-webservices/OncoKB-Data-Access.md index adda174d2a3..ee40a2bff47 100644 --- a/docs/deployment/integration-with-other-webservices/OncoKB-Data-Access.md +++ b/docs/deployment/integration-with-other-webservices/OncoKB-Data-Access.md @@ -9,7 +9,7 @@ If you want to include tumor type summary, therapeutic levels and more, please c 3. You can find your token in your [Account Settings](https://www.oncokb.org/account/settings) after login. # Set up cBioPortal to include full OncoKB content -Following properties can be edited in the `portal.properties` file or set in system variables if you are using docker. +Following properties can be edited in the `application.properties` file or set in system variables if you are using docker. - `show.oncokb` should be set to `true` - `oncokb.token` should be set to a valid OncoKB access token value - `oncokb.public_api.url` should be set to `https://www.oncokb.org/api/v1` @@ -23,4 +23,4 @@ For TMB-H, a clinical attribute TMB_SCORE with value >=10 is required. # Disable OncoKB Service -Please set `show.oncokb` to `false` in `portal.properties` or in system variables if you are using docker. +Please set `show.oncokb` to `false` in `application.properties` or in system variables if you are using docker. diff --git a/docs/development/Deployment-Procedure.md b/docs/development/Deployment-Procedure.md index 1aabe789247..c37eed94935 100644 --- a/docs/development/Deployment-Procedure.md +++ b/docs/development/Deployment-Procedure.md @@ -5,16 +5,12 @@ see e.g. [Deploying the web application](/deployment/deploy-without-docker/Deplo Docker](/deployment/docker/). We deploy the master branch of backend and the master branch of frontend to -production. The public portal (https://www.cbioportal.org) runs on AWS inside -kubernetes. The configuration can be found in the knowledgesystems repo: +production. The public portal (https://www.cbioportal.org) runs on AWS EKS. The configuration +can be found in the knowledgesystems repo: https://github.com/knowledgesystems/knowledgesystems-k8s-deployment -Other portals run at MSKCC on two internal machines called dashi and dashi2. -Since we're running several apps in several tomcats internally the procedure -for updating them is different from the public portal on AWS. The configuration -is in the mercurial portal-configuration repo. To make changes, ask Ben for -access. +Other internal MSK portals run on AWS EKS as well. The frontend and backend can be upgraded independently. We have the following events that can require a new deployment: @@ -40,7 +36,7 @@ This should be a URL pointing to netlify. ### Internal Portal Frontend URL For the internally runnning portals the frontend.url is defined in the -portal.properties file in the mercurial portal-configuration repo. If set up +application.properties file in the mercurial portal-configuration repo. If set up correctly, this should point to a file on both dashi and dashi2 that in turn points to a netlify frontend URL. The reason we have a separate file with the URL in it is that it allows us to update the frontend URL without redeploying @@ -56,13 +52,12 @@ Once the backend repo has been tagged on github, a docker image gets build on Do After that, if you have access to the kubernetes cluster you can change the image in the configuration of the kubernetes cluster: - -https://github.com/knowledgesystems/knowledgesystems-k8s-deployment/blob/master/cbioportal/cbioportal_spring_boot.yaml +https://github.com/knowledgesystems/knowledgesystems-k8s-deployment/blob/master/public-eks/cbioportal-prod/cbioportal_spring_boot.yaml point this line, to the new tag on docker hub e.g.: ``` -image: cbioportal/cbioportal:3.0.3-web-shenandoah +image: cbioportal/cbioportal:6.0.2-web-shenandoah ``` Make sure it is an image with the postfix `-web-shenandoah`. This is the image that only has the web part of cBioPortal and uses the shenandoah garbage collector. @@ -76,7 +71,7 @@ Also remove the `-Dfrontend.url` parameter such that the frontend version inside Then running this command applies the changes to the cluster: ``` -kubectl apply -f cbioportal/cbioportal_spring_boot.yaml +kubectl apply -f public-eks/cbioportal-prod/cbioportal_spring_boot.yaml ``` You can keep track of what's happening by looking at the pods: @@ -109,71 +104,9 @@ Make sure to commit your changes to the knowledgesystems-k8s-deployment repo and push them to the main repo, so that other people making changes to the kubernetes config will be using the latest version. -### Private Portal Backend Upgrade -First update the frontend portal configuration to point to a new file. It's -fine if this file does not exist yet, because if it doesn't the frontend -bundled with the war will be used. We can later point the file to netlify, once -we've determined everything looks ok. - -You can use this for loop to update the frontend url in all properties files -(set it to a file that doesn't exist yet and give it a sensible name e.g. `frontend_url_version_x_y_z.txt`): - -``` -for f in $(grep frontend.url.runtime properties/*/portal.properties | grep -v beta | cut -d: -f1); do sed -i 's|frontend.url.runtime=/srv/www/msk-tomcat/frontend_url_version_2_0_0.txt|frontend.url.runtime=/srv/www/msk-tomcat/frontend_url_version_2_1_0.txt|g' $f; done -``` -Same for triage-tomcat (agin set the correct file name):: - -``` - for f in $(grep frontend.url.runtime properties/*/portal.properties | grep -v beta | cut -d: -f1); do sed -i 's|frontend.url.runtime=/srv/www/triage-tomcat/frontend_url_version_2_0_0.txt|frontend.url.runtime=/srv/www/triage-tomcat/frontend_url_version_2_1_0.txt|g' $f; done -``` - -Make sure you see the frontend url file updated correctly: - -``` -hg diff -``` - -Then commit and push your changes to the mercurial repo: -``` -hg commit -u username -m 'update frontend url files for new release' -hg push -``` - -If you have your public key added for the relevant deploy scripts you should be able to deploy with the following command on dashi-dev: - -``` -# set PROJECT_CONFIG_HOME and PORTAL_HOME to your own directory -unset PROJECT_VERSION && export PORTAL_HOME=/data/debruiji/git/cbioportal && export PORTAL_CONFIG_HOME=/data/debruiji/hg/portal-configuration && cd ${PORTAL_CONFIG_HOME}/buildwars && hg pull && hg update && export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk.x86_64 && bash buildproductionwars.sh master && bash ${PORTAL_CONFIG_HOME}/deploywars-remotely/deployproductionportals.sh -``` - -If you don't have a SSH key set up to run the deploy script ask Ino. - -If everything looks ok you can update the frontend url file to point to -netlify. Log in to dashi and become msk-tomcat with `sudo su - msk-tomcat`. -Then change the update script: - -``` -vi /data/cbio-portal-data/portal-configuration/deploy-scripts/updatefrontendurl.sh -``` -to point `oldurlfile=/srv/www/msk-tomcat/frontend_url_version_2_0_0.txt` to the -new frontend url file you supplied above. - -Then update the url like: - -``` -./updatefrontendurl.sh "https://frontend.cbioportal.org" -``` - -Do the same thing on dashi2. - -The last step is to modify the frontend url file for the triage portal. Log in to the pipelines machine, log in as triage-tomcat user: `sudo su - triage-tomcat`, and update the frontend url file there: - -``` -echo 'https://frontend.cbioportal.org' > /srv/www/triage-tomcat/frontend_url_version_2_1_0.txt -``` ## Upgrading Related Backend Components -Backend upgrades involving the database schema, DAO classes, etc. require updates to databases and importers. CBioPortal has multiple databases (located both internally on pipelines and in AWS) backing different portals. Similarly there are multiple importers responsible for loading portal-specific data. Every database must be manually migrated on an individual basis; all importers/data fetchers can be updated simultaenously through an existing deployment script. +Backend upgrades involving the database schema, DAO classes, etc. require updates to databases and importers. CBioPortal has multiple MySQL databases (all using AWS RDS) backing different portals. Similarly, there are multiple importers responsible for loading portal-specific data. Every database must be manually migrated on an individual basis; all importers/data fetchers can be updated simultaneously through an existing deployment script. Before upgrading, make sure to turn off import jobs in the crontab and alert the backend pipelines team (Avery, Angelica, Rob, Manda). diff --git a/docs/development/Release-Procedure.md b/docs/development/Release-Procedure.md index cec9d32f48a..28e405fc48d 100644 --- a/docs/development/Release-Procedure.md +++ b/docs/development/Release-Procedure.md @@ -7,7 +7,7 @@ We have release procedures for the following scenarios: ## cBioPortal community release of code already in production -We often run code in production that is not ready yet for use by the wider cBioPortal community. We deploy to production what's in the master branch of the backend repo and the frontend repo. Often times this is not a tagged release. At some point this code should be released for the wider community. These are the steps we follow: +We often run code in production that is not ready yet for use by the wider cBioPortal community. The frontend gets deployed to production after every merge to master. The backend gets updated every Tuesday before our community call (occasionally more frequently too if issues are identified). We tag whatever is in the master and frontend repo and put a "Pre-Release" indication on it. After a month of stable usage in production, one of the tags will get the "latest" indication on the GitHub. These are the steps we follow to create a release: 1. Create a new frontend tag. The releases can be found here: https://github.com/cBioPortal/cbioportal-frontend/releases. A draft of the release notes are automatically generated by https://github.com/marketplace/actions/release-drafter. If there are pull requests in the `Changes` section i.e. they have not been labeled with one of the labels defined [here](https://github.com/cBioPortal/cbioportal-frontend/blob/master/.github/release-drafter.yml). Try to label them and trigger a rerun by committing something to the master branch. Alternatively you can manually put them in a particular section. Note that our goal is to have automated release notes, so it would be great if you could send a PR to update the [release-drafter.yml](https://github.com/cBioPortal/cbioportal-frontend/blob/master/.github/release-drafter.yml) in case you find certain PRs don't fit in a particular section or a section should be altered. Look at other release notes for inspiration: https://github.com/cBioPortal/cbioportal-frontend/releases. You can save your work as a draft if necessary. 2. Once the frontend code is tagged, create a pull request to the backend repo where the frontend version is incremented in `portal/pom.xml`: @@ -26,6 +26,9 @@ We often run code in production that is not ready yet for use by the wider cBioP then put them in the right sections following same style as other releases: https://github.com/cBioPortal/cbioportal-frontend/releases. 4. Create a news item with a link to your carefully crafted release notes. Highlight a few major changes that could be interesting to users of cBioPortal ideally with a screenshot similar to: https://github.com/cBioPortal/cbioportal/pull/6914/files?short\_path=6f95322#diff-6f953229832059bab3fe229d4af08b52 (in the files changed section, you can click on view rich diff to see the converted markdown). +## Backend Hotfixes +Occasionally there are bugs identified in the backend running in production. Creating an entire new release can be cumbersome so in this case, we create a new release branch instead. E.g. if the current release is `6.0.2`, the new branch would be `release-6.0.3`. Any fixes are then merged to this branch and if it looks good, they are deployed to production. On the following Tuesday whatever's in this `release-x` branch get merged to master and included in that Tuesday's release. + ## Release with database migration For releases with database migrations, we increase the MINOR number in MAJOR.MINOR.PATCH. For those releases we have a separate branch (see https://github.com/cBioPortal/cbioportal/blob/master/CONTRIBUTING.md#branches-within-cbioportal), which needs to be merged to master on both backend and frontend: diff --git a/docs/development/feature-development-guide.md b/docs/development/feature-development-guide.md index 2ef0acf99de..5a9ddcc75b2 100644 --- a/docs/development/feature-development-guide.md +++ b/docs/development/feature-development-guide.md @@ -4,9 +4,9 @@ This is a guide for developers that are implementing a new feature. ## Before Implementation -As a first step it is important to determine how complex the proposed feature is. Incremental improvements on existing features are often easier to accomplish and require input from fewer people. Most minor changes can be submitted as a Pull Request. If the proposed feature would require one or more days of work it makes sense to connect on [slack](https://slack.cbioportal.org) to discuss the idea. For more complex new features that require weeks of work or more, it is best to get input from several people in the cBioPortal community, including people with a deep understanding of the cBioPortal product and its users as well as the engineers that write the software. In that case we often start out with a Request For Comments document that describes the feature in more detail, see [our list of RFCs ](RFC-List.md)for some examples. The community can then help guide the feature development in the right direction. +As a first step it is important to determine how complex the proposed feature is. Incremental improvements on existing features are often easier to accomplish and require input from fewer people. Most minor changes can be submitted as a Pull Request. If the proposed feature would require one or more days of work it makes sense to connect on [slack](https://slack.cbioportal.org) to discuss the idea. For more complex new features that require weeks of work or more, it is best to get input from several people in the cBioPortal community, including people with a deep understanding of the cBioPortal product and its users as well as the engineers that write the software. In that case we often start out with a Request For Comments document that describes the feature in more detail, see [our list of RFCs ](../RFC-List.md)for some examples. The community can then help guide the feature development in the right direction. -During this process you will most likely receive some pointers which part of the stack you will be editing (see [Architecture Overview](Architecture-Overview.md)). This will be helpful when actually starting your implementation and figuring out how to set up your development environment. For many features it is not necessary to understand all parts of the stack, so seeking out advice on this is highly recommended. +During this process you will most likely receive some pointers which part of the stack you will be editing (see [Architecture Overview](../Architecture-Overview.md)). This will be helpful when actually starting your implementation and figuring out how to set up your development environment. For many features it is not necessary to understand all parts of the stack, so seeking out advice on this is highly recommended. Before you start implementing a more complex feature, ideally many of these things are clear: diff --git a/docs/mutation-data-transcript-annotation.md b/docs/mutation-data-transcript-annotation.md index 8fb15021f00..f19cc74daa2 100644 --- a/docs/mutation-data-transcript-annotation.md +++ b/docs/mutation-data-transcript-annotation.md @@ -42,7 +42,7 @@ starting from scratch, since these are more up to date and correspond to transcr clinical sequencing at MSKCC. The `uniprot` set of transcripts was constructed several years ago, but we are no longer certain about the logic on how to reconstruct them hence they are not being kept up to date. One can see the differences between the two in [this file](https://github.com/cBioPortal/cbioportal-frontend/files/9498680/genes_with_different_uniprot_mskcc_isoforms.txt). For the public cBioPortal (https: -//www.cbioportal.org) and [datahub](https://github.com/cBioPortal/datahub/tree/master/public) we are using `mskcc`, for the GENIE cBioPortal (https://genie.cbioportal.org) we still use `uniprot`. As of cBioPortal v5 the default is `mskcc` for local installations. Prior to v5 it was `uniprot`. We recommend that people upgrading to v5 consider migrating to `mskcc` as well (see [migration guide](https://docs.cbioportal.org/migration-guide/) and [the properties reference docs](https://docs.cbioportal.org/deployment/customization/portal.properties-reference/#properties)). +//www.cbioportal.org) and [datahub](https://github.com/cBioPortal/datahub/tree/master/public) we are using `mskcc`, for the GENIE cBioPortal (https://genie.cbioportal.org) we still use `uniprot`. As of cBioPortal v5 the default is `mskcc` for local installations. Prior to v5 it was `uniprot`. We recommend that people upgrading to v5 consider migrating to `mskcc` as well (see [migration guide](https://docs.cbioportal.org/migration-guide/) and [the properties reference docs](https://docs.cbioportal.org/deployment/customization/application.properties-reference/#properties)). #### How default transcript assignment affects the Mutations Tab @@ -52,7 +52,7 @@ protein position found in the cBioPortal database. For the [public cBioPortal](h data in MAF format are annotated using [Genome Nexus](https://www.genomenexus.org) to add the gene and protein change columns. This is then imported into the cBioPortal database. Whether you choose to use the set of `uniprot` or `mskcc` transcripts, make sure to indicate it in the [Genome Nexus Annotation Pipeline](https://github.com/genome-nexus/genome- -nexus-annotation-pipeline#maf-annotation)(`--isoform-override `) when annotating as well as in [the properties file](https://docs.cbioportal.org/deployment/customization/portal.properties-reference/#properties) +nexus-annotation-pipeline#maf-annotation)(`--isoform-override `) when annotating as well as in [the properties file](https://docs.cbioportal.org/deployment/customization/application.properties-reference/#properties) of cBioPortal. That way the [Mutations Tab](https://bit.ly/39hVtDd) will show the correct canonical transcript. Note that whenever somebody uses the dropdown on the Mutations Tab to change the displayed transcript, Genome Neuxs re-annotates all mutations on the fly. The browser sends over the genomic location (chrom,start,end,ref, @@ -65,4 +65,4 @@ We are planning to move to a single set of default transcripts over time. Prior facing portals and local installations. Our plan is to use `mskcc` everywhere and eventually we will most likely move to [MANE](https://www.ensembl.org/info/genome/genebuild/mane.html). MANE is only available for grch38 and since most of our data is for grch37 this is currently not feasible. Whichever set of transcripts you choose to use, make sure to indicate so in the [Genome Nexus Annotation Pipeline](https://github.com/genome-nexus/genome-nexus-annotation-pipeline#maf-annotation) (`--isoform-override `) and put the same -set of transcripts in [the properties file](https://docs.cbioportal.org/deployment/customization/portal.properties-reference/#properties) of cBioPortal, such that the [Mutations Tab](https://bit.ly/39hVtDd) will show the correct canonical transcript (currently defaults to `mskcc`). The re-annotation of mutations only happens once a user clicks to change the transcript, which is why it's important that the protein change in the database is for the specific transcript displayed first. +set of transcripts in [the properties file](https://docs.cbioportal.org/deployment/customization/application.properties-reference/#properties) of cBioPortal, such that the [Mutations Tab](https://bit.ly/39hVtDd) will show the correct canonical transcript (currently defaults to `mskcc`). The re-annotation of mutations only happens once a user clicks to change the transcript, which is why it's important that the protein change in the database is for the specific transcript displayed first. diff --git a/docs/user-guide/overview.md b/docs/user-guide/overview.md index ae18a16339e..6ff6f649d94 100644 --- a/docs/user-guide/overview.md +++ b/docs/user-guide/overview.md @@ -1,4 +1,4 @@ -## Overview of Resources +## Tutorials ### Tutorial Slides These tutorial slides contain annoted screenshots to walk you through using the cBioPortal site. @@ -35,6 +35,7 @@ Short videos that show how to perform specific analyses or how to use specific p * Onco Query Language [OQL](/user-guide/oql.md) ### Publications +* de Bruijn et al. Cancer Research (2023) [PubMed](https://pubmed.ncbi.nlm.nih.gov/37668528/) * Cerami et al. Cancer Discovery 2012 [PubMed](http://cancerdiscovery.aacrjournals.org/content/2/5/401.abstract) * Gao et al. Science Signaling 2013 [PubMed](https://www.ncbi.nlm.nih.gov/pubmed/23550210) diff --git a/docs/web-API-and-Clients.md b/docs/web-API-and-Clients.md index 762f0da3649..5ce1ac34590 100644 --- a/docs/web-API-and-Clients.md +++ b/docs/web-API-and-Clients.md @@ -115,14 +115,17 @@ muts = cbioportal.mutations.getMutationsInMolecularProfileBySampleListIdUsingGET For a portal that requires authentication one can use (see [Data Access Using Tokens](/deployment/authorization-and-authentication/Authenticating-Users-via-Tokens.md)): ``` -headers = { - 'Authorization': 'Bearer 63efa81c-2490-4e15-9d1c-fb6e8e50e35d' -} -requestOptions = { - 'headers': headers, -} +from bravado.client import SwaggerClient +from bravado.requests_client import RequestsClient + +http_client = RequestsClient() +http_client.set_api_key( + 'genie.cbioportal.org', 'Bearer ', + param_name='Authorization', param_in='header' +) + cbioportal = SwaggerClient.from_url('https://genie.cbioportal.org/api/v2/api-docs', - request_headers=headers, + http_client=http_client, config={"validate_requests":False, "validate_responses":False, "validate_swagger_spec": False} diff --git a/pom.xml b/pom.xml index 575da41b367..0cc9b9c0110 100644 --- a/pom.xml +++ b/pom.xml @@ -12,31 +12,32 @@ org.cbioportal cbioportal - 6.0.0-SNAPSHOT + 6.0.6-SNAPSHOT cBioPortal for Cancer Genomics - 21 - 21 - + 21 + 21 + 21 + 21 + 21 yyyyMMdd-HHmm ${maven.build.timestamp} com.github.cbioportal - v5.4.9 + v6.0.5 - + 2.13.1 1.1.6.RELEASE - 2.12.5 - 5.1.48 + 8.0.28 3.0.0 UTF-8 UTF-8 @@ -46,8 +47,17 @@ ${project.groupId}:${project.artifactId} cbioportal https://sonarcloud.io + **src/test/**/*.* + + + 0.8.11 + jacoco + reuseReports + java + + ${project.basedir}/target/site/jacoco/jacoco.xml + - com.mysql.jdbc.Driver @@ -63,8 +73,8 @@ 1.6.3 3.0.2 - 1.16.2 - 5.8.0 + 1.19.4 + 5.15.0 4.1.1 @@ -83,9 +93,11 @@ 1.1.1 3.12.14 0.8.2 - 5.1.48 - 1.8.1 + 8.0.33 + 3.2.0 3.14.0 + 4.17.0 + 7.1.0 @@ -103,11 +115,11 @@ spring-boot-starter-test test - - org.junit.vintage - junit-vintage-engine - test - + + org.junit.vintage + junit-vintage-engine + test + org.slf4j slf4j-api @@ -178,10 +190,6 @@ jjwt-jackson ${io-jsonwebtoken.version} - - org.springframework.boot - spring-boot-starter-data-mongodb - org.mongodb bson @@ -239,6 +247,16 @@ org.springframework.security spring-security-web + + org.springframework.security + spring-security-jwt + 1.1.1.RELEASE + + + com.auth0 + jwks-rsa + 0.22.1 + mysql mysql-connector-java @@ -248,23 +266,17 @@ org.springframework.boot spring-boot-starter-thymeleaf - - com.github.dasniko - testcontainers-keycloak - ${dasniko-testcontainer-keycload.version} - test - org.springframework.security spring-security-test test - - org.seleniumhq.selenium - selenium-chrome-driver - ${selenium_chrome_driver.version} - test - + + org.seleniumhq.selenium + selenium-java + ${selenium.version} + test + org.testcontainers testcontainers @@ -275,7 +287,24 @@ mysql test - + + org.testcontainers + mockserver + test + + + org.mock-server + mockserver-client-java + ${mockserver.version} + test + + + com.github.dasniko + testcontainers-keycloak + ${dasniko-testcontainer-keycloak.version} + test + + org.testcontainers selenium test @@ -292,35 +321,52 @@ maven-simple 0.1 - - - org.springframework.boot - spring-boot-starter-oauth2-client - - - org.springframework.boot - spring-boot-starter-oauth2-resource-server - - - org.springframework.security - spring-security-saml2-service-provider - - - org.springframework.session - spring-session-data-redis - + + + org.springframework.boot + spring-boot-starter-oauth2-client + + + org.springframework.boot + spring-boot-starter-oauth2-resource-server + + + org.springframework.security + spring-security-saml2-service-provider + + + org.springframework.session + spring-session-data-redis + org.springframework.boot spring-boot-starter-data-redis - - org.springframework.boot - spring-boot-devtools - runtime - true - + + org.springframework.boot + spring-boot-devtools + runtime + true + + + io.sentry + sentry-spring-boot-starter-jakarta + ${sentry.version} + + + + + org.testcontainers + testcontainers-bom + ${testcontainers.version} + pom + import + + + + cbioportal @@ -380,13 +426,13 @@ org.springframework.boot spring-boot-maven-plugin - - repackage - - exec - - - + + repackage + + exec + + + @@ -449,8 +495,60 @@ org.apache.maven.plugins maven-wrapper-plugin + + org.jacoco + jacoco-maven-plugin + ${jacoco.version} + + + default-prepare-agent + + prepare-agent + + + + default-report + + report + + + + XML + + + + + - + + + org.apache.maven.plugins + maven-surefire-plugin + + ${skipTests} + + **/*IntegrationTest.java + + + + + maven-failsafe-plugin + + ${skipITs} + + **/*IntegrationTest.java + + + + + + integration-test + verify + + + + + diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 5cd1f3ba8b7..00000000000 --- a/requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -requests==2.20.0 -markupsafe==2.0.1 -Jinja2==2.11.3 -mysqlclient==2.1.0 -PyYAML==6.0.1 -dsnparse==0.1.15 diff --git a/src/main/java/org/cbioportal/PortalApplication.java b/src/main/java/org/cbioportal/PortalApplication.java index 5aded5fa465..97844cb926b 100644 --- a/src/main/java/org/cbioportal/PortalApplication.java +++ b/src/main/java/org/cbioportal/PortalApplication.java @@ -12,7 +12,7 @@ MongoDataAutoConfiguration.class }) @PropertySources({ - @PropertySource(ignoreResourceNotFound = true, value = "classpath:portal.properties"), + @PropertySource(ignoreResourceNotFound = true, value = "classpath:application.properties"), @PropertySource(ignoreResourceNotFound = true, value = "classpath:security.properties"), @PropertySource(ignoreResourceNotFound = true, value = "classpath:maven.properties"), @PropertySource(ignoreResourceNotFound = true, value = "classpath:git.properties") diff --git a/src/main/java/org/cbioportal/WebAppConfig.java b/src/main/java/org/cbioportal/WebAppConfig.java index 612884dad51..2ea3e019d65 100644 --- a/src/main/java/org/cbioportal/WebAppConfig.java +++ b/src/main/java/org/cbioportal/WebAppConfig.java @@ -1,10 +1,14 @@ package org.cbioportal; +import java.util.List; + import org.cbioportal.web.util.InvolvedCancerStudyExtractorInterceptor; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -15,50 +19,68 @@ //@EnableAspectJAutoProxy // TODO no idea what this does; is this logging aspect still useful? public class WebAppConfig implements WebMvcConfigurer { - private static final String SINGLE_PAGE_APP_ROOT = "forward:/"; + private static final String SINGLE_PAGE_APP_ROOT = "forward:/"; + + @Value("${springdoc.swagger-ui.path:/swagger-ui.html}") + private String swaggerRedirectUrl; + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/images/**").addResourceLocations("classpath:/webapp/images/"); + registry.addResourceHandler("/reactapp/**").addResourceLocations("classpath:/reactapp/"); + registry.addResourceHandler("/js/**").addResourceLocations("classpath:/js/"); + } + + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addRedirectViewController("/api", swaggerRedirectUrl); + registry.addRedirectViewController("/installations", "https://installationmap.netlify.app/"); + registry.addRedirectViewController("/tutorials", "https://docs.cbioportal.org/user-guide/overview/#tutorial-slides"); + registry.addRedirectViewController("/oql", "https://docs.cbioportal.org/user-guide/oql/"); + registry.addRedirectViewController("/faq", "https://docs.cbioportal.org/user-guide/faq/"); + + List endpoints = List.of( + "/results/*", + "/results**", + "/patient/*", + "/patient**", + "/study/*", + "/study", + "/mutation_mapper/*", + "/mutation_mapper", + "/index.do/*", + "/case.do/*", + "/loading/*", + "/comparison", + "/comparison/*", + "/restore", + "/index.do**", + "/oncoprinter**", + "/encodedRedirect", + "/datasets**", + "/ln**", + "/webAPI**", + "/news**", + "/visualize**" + ); + + endpoints.forEach( route -> registry.addViewController(route).setViewName(SINGLE_PAGE_APP_ROOT)); + } - @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { - registry.addResourceHandler("/images/**").addResourceLocations("classpath:/webapp/images/"); - registry.addResourceHandler("/reactapp/**").addResourceLocations("classpath:/reactapp/"); - registry.addResourceHandler("/js/**").addResourceLocations("classpath:/js/"); - } + @Bean + public HandlerInterceptor involvedCancerStudyExtractorInterceptor() { + return new InvolvedCancerStudyExtractorInterceptor(); + } - @Override - public void addViewControllers(ViewControllerRegistry registry) { - registry.addRedirectViewController("/api", "/swagger-ui.html"); - - - // Redirects for single page app - registry.addViewController("/results/*").setViewName(SINGLE_PAGE_APP_ROOT); - registry.addViewController("/results**").setViewName(SINGLE_PAGE_APP_ROOT); - registry.addViewController("/patient/*").setViewName(SINGLE_PAGE_APP_ROOT); - registry.addViewController("/patient**").setViewName(SINGLE_PAGE_APP_ROOT); - registry.addViewController("/study/*").setViewName(SINGLE_PAGE_APP_ROOT); - registry.addViewController("/study").setViewName(SINGLE_PAGE_APP_ROOT); - registry.addViewController("/mutation_mapper/*").setViewName(SINGLE_PAGE_APP_ROOT); - registry.addViewController("/mutation_mapper").setViewName(SINGLE_PAGE_APP_ROOT); - registry.addViewController("/index.do/*").setViewName(SINGLE_PAGE_APP_ROOT); - registry.addViewController("/case.do/*").setViewName(SINGLE_PAGE_APP_ROOT); - registry.addViewController("/loading/*").setViewName(SINGLE_PAGE_APP_ROOT); - registry.addViewController("/comparison").setViewName(SINGLE_PAGE_APP_ROOT); - registry.addViewController("/comparison/*").setViewName(SINGLE_PAGE_APP_ROOT); - registry.addViewController("/restore").setViewName(SINGLE_PAGE_APP_ROOT); - registry.addViewController("/index.do**").setViewName(SINGLE_PAGE_APP_ROOT); - registry.addViewController("/oncoprinter**").setViewName(SINGLE_PAGE_APP_ROOT); - registry.addViewController("/encodedRedirect").setViewName(SINGLE_PAGE_APP_ROOT); - registry.addViewController("/datasets**").setViewName(SINGLE_PAGE_APP_ROOT); + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(involvedCancerStudyExtractorInterceptor()); + } - } - - @Bean - public HandlerInterceptor involvedCancerStudyExtractorInterceptor() { - return new InvolvedCancerStudyExtractorInterceptor(); - } + @Override + public void configurePathMatch(PathMatchConfigurer configurer) { + // Adds support for trailing slash Matches + configurer.setUseTrailingSlashMatch(true); + } - @Override - public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(involvedCancerStudyExtractorInterceptor()); - } - } diff --git a/src/main/java/org/cbioportal/model/CancerStudy.java b/src/main/java/org/cbioportal/model/CancerStudy.java index 48ed6103abb..8504a8bd55a 100644 --- a/src/main/java/org/cbioportal/model/CancerStudy.java +++ b/src/main/java/org/cbioportal/model/CancerStudy.java @@ -33,6 +33,7 @@ public class CancerStudy implements ReadPermission, Serializable { private String referenceGenome; private Boolean readPermission = true; private Integer treatmentCount; + private Integer structuralVariantCount; public Integer getCancerStudyId() { return cancerStudyId; @@ -239,4 +240,12 @@ public Integer getTreatmentCount() { public void setTreatmentCount(Integer treatmentCount) { this.treatmentCount = treatmentCount; } + + public Integer getStructuralVariantCount() { + return structuralVariantCount; + } + + public void setStructuralVariantCount(Integer structuralVariantCount) { + this.structuralVariantCount = structuralVariantCount; + } } diff --git a/src/main/java/org/cbioportal/model/GenomicDataCount.java b/src/main/java/org/cbioportal/model/GenomicDataCount.java index a9d8862f4d5..fcc8587c69c 100644 --- a/src/main/java/org/cbioportal/model/GenomicDataCount.java +++ b/src/main/java/org/cbioportal/model/GenomicDataCount.java @@ -8,6 +8,7 @@ public class GenomicDataCount implements Serializable { private String label; private String value; private Integer count; + private Integer uniqueCount; public String getLabel() { return label; @@ -33,16 +34,20 @@ public void setCount(Integer count) { this.count = count; } + public Integer getUniqueCount() { return uniqueCount; } + + public void setUniqueCount(Integer uniqueCount) { this.uniqueCount = uniqueCount; } + @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; GenomicDataCount that = (GenomicDataCount) o; - return label.equals(that.label) && value.equals(that.value) && count.equals(that.count); + return Objects.equals(label, that.label) && Objects.equals(value, that.value) && Objects.equals(count, that.count) && Objects.equals(uniqueCount, that.uniqueCount); } @Override public int hashCode() { - return Objects.hash(label, value, count); + return Objects.hash(label, value, count, uniqueCount); } } diff --git a/src/main/java/org/cbioportal/model/MutationFilterOption.java b/src/main/java/org/cbioportal/model/MutationFilterOption.java new file mode 100644 index 00000000000..fd83da4f051 --- /dev/null +++ b/src/main/java/org/cbioportal/model/MutationFilterOption.java @@ -0,0 +1,18 @@ +package org.cbioportal.model; + +public enum MutationFilterOption { + MUTATED("Mutated"), // Samples that have mutations + NOT_MUTATED("Not Mutated"), // Samples that are profiled and not mutated + NOT_PROFILED("Not Profiled"), // Samples that are not profiled + ; + + private final String selectedOption; + + MutationFilterOption(String selectedOption) { + this.selectedOption = selectedOption; + } + + public String getSelectedOption() { + return selectedOption; + } +} diff --git a/src/main/java/org/cbioportal/persistence/MutationRepository.java b/src/main/java/org/cbioportal/persistence/MutationRepository.java index ac25c83f9ff..ffcef1b6f0c 100644 --- a/src/main/java/org/cbioportal/persistence/MutationRepository.java +++ b/src/main/java/org/cbioportal/persistence/MutationRepository.java @@ -1,6 +1,7 @@ package org.cbioportal.persistence; import org.cbioportal.model.GeneFilterQuery; +import org.cbioportal.model.GenomicDataCountItem; import org.cbioportal.model.Mutation; import org.cbioportal.model.MutationCountByPosition; import org.cbioportal.model.meta.MutationMeta; @@ -12,7 +13,7 @@ public interface MutationRepository { @Cacheable(cacheResolver = "generalRepositoryCacheResolver", condition = "@cacheEnabledConfig.getEnabled()") List getMutationsInMolecularProfileBySampleListId(String molecularProfileId, String sampleListId, - List entrezGeneIds, Boolean snpOnly, + List entrezGeneIds, boolean snpOnly, String projection, Integer pageSize, Integer pageNumber, String sortBy, String direction); @@ -43,7 +44,7 @@ MutationMeta getMetaMutationsInMultipleMolecularProfiles(List molecularP @Cacheable(cacheResolver = "generalRepositoryCacheResolver", condition = "@cacheEnabledConfig.getEnabled()") List fetchMutationsInMolecularProfile(String molecularProfileId, List sampleIds, - List entrezGeneIds, Boolean snpOnly, String projection, + List entrezGeneIds, boolean snpOnly, String projection, Integer pageSize, Integer pageNumber, String sortBy, String direction); @@ -54,4 +55,8 @@ MutationMeta fetchMetaMutationsInMolecularProfile(String molecularProfileId, Lis @Cacheable(cacheResolver = "generalRepositoryCacheResolver", condition = "@cacheEnabledConfig.getEnabled()") MutationCountByPosition getMutationCountByPosition(Integer entrezGeneId, Integer proteinPosStart, Integer proteinPosEnd); + + @Cacheable(cacheResolver = "generalRepositoryCacheResolver", condition = "@cacheEnabledConfig.getEnabled()") + GenomicDataCountItem getMutationCountsByType(List molecularProfileIds, List sampleIds, + List entrezGeneIds, String profileType); } diff --git a/src/main/java/org/cbioportal/persistence/cachemaputil/InactiveCacheMapUtil.java b/src/main/java/org/cbioportal/persistence/cachemaputil/InactiveCacheMapUtil.java index 58d8d2d1744..8213ede2aaf 100644 --- a/src/main/java/org/cbioportal/persistence/cachemaputil/InactiveCacheMapUtil.java +++ b/src/main/java/org/cbioportal/persistence/cachemaputil/InactiveCacheMapUtil.java @@ -1,49 +1,20 @@ -/* - * Copyright (c) 2018 - 2019 Memorial Sloan-Kettering Cancer Center. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - * obligations to provide maintenance, support, updates, enhancements or - * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - * liable to any party for direct, indirect, special, incidental or - * consequential damages, including lost profits, arising out of the use of this - * software and its documentation, even if Memorial Sloan-Kettering Cancer - * Center has been advised of the possibility of such damage. - */ - -/* - * This file is part of cBioPortal. - * - * cBioPortal is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - package org.cbioportal.persistence.cachemaputil; -import java.util.Map; import org.cbioportal.model.CancerStudy; import org.cbioportal.model.MolecularProfile; import org.cbioportal.model.SampleList; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.stereotype.Component; +import java.util.Map; + @Component // This implementation of the CacheMapUtils is instantiated on portals where all uses can access any study. +@ConditionalOnExpression("'false' eq '${authenticate}' or ('optional_oauth2' eq '${authenticate}' and 'true' ne '${security.method_authorization_enabled}')") public class InactiveCacheMapUtil implements CacheMapUtil { // Since user-permission evaluation is not needed when this bean is present, throw an error when it is accessed. - + @Override public Map getMolecularProfileMap() { throw new RuntimeException("A CacheMapUtils method was called on a portal where studies are accessible to all users."); @@ -65,4 +36,4 @@ public boolean hasCacheEnabled() { return false; } -} +} \ No newline at end of file diff --git a/src/main/java/org/cbioportal/persistence/cachemaputil/SpringManagedCacheMapUtil.java b/src/main/java/org/cbioportal/persistence/cachemaputil/SpringManagedCacheMapUtil.java index 5eae44a6812..e58f04b6cf5 100644 --- a/src/main/java/org/cbioportal/persistence/cachemaputil/SpringManagedCacheMapUtil.java +++ b/src/main/java/org/cbioportal/persistence/cachemaputil/SpringManagedCacheMapUtil.java @@ -40,12 +40,17 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Component; import java.util.Map; -//@Component +@Component // Instantiate when user authorization is active and spring-managed implementation is needed +@ConditionalOnExpression("{'oauth2','saml','saml_plus_basic'}.contains('${authenticate}') or ('optional_oauth2' eq '${authenticate}' and 'true' eq '${security.method_authorization_enabled}')") +@ConditionalOnProperty(value = "cache.cache-map-utils.spring-managed", havingValue = "true") public class SpringManagedCacheMapUtil implements CacheMapUtil { private static final Logger LOG = LoggerFactory.getLogger(SpringManagedCacheMapUtil.class); diff --git a/src/main/java/org/cbioportal/persistence/cachemaputil/StaticRefCacheMapUtil.java b/src/main/java/org/cbioportal/persistence/cachemaputil/StaticRefCacheMapUtil.java index ce598fbbbd1..48d07e0bff1 100644 --- a/src/main/java/org/cbioportal/persistence/cachemaputil/StaticRefCacheMapUtil.java +++ b/src/main/java/org/cbioportal/persistence/cachemaputil/StaticRefCacheMapUtil.java @@ -39,12 +39,16 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Component; import java.util.Map; @Component // Instantiate when user authorization is active and spring-managed implementation is not needed +@ConditionalOnExpression("{'oauth2','saml','saml_plus_basic'}.contains('${authenticate}') or ('optional_oauth2' eq '${authenticate}' and 'true' eq '${security.method_authorization_enabled}')") +@ConditionalOnProperty(value = "cache.cache-map-utils.spring-managed", havingValue = "false", matchIfMissing = true) public class StaticRefCacheMapUtil implements CacheMapUtil { private static final Logger LOG = LoggerFactory.getLogger(StaticRefCacheMapUtil.class); @@ -62,7 +66,6 @@ public class StaticRefCacheMapUtil implements CacheMapUtil { static Map molecularProfileCache; static Map sampleListCache; static Map cancerStudyCache; - static Map genericAssayStableIdToMolecularProfileIdCache; @PostConstruct private void init() { diff --git a/src/main/java/org/cbioportal/persistence/mybatis/MutationMapper.java b/src/main/java/org/cbioportal/persistence/mybatis/MutationMapper.java index d65713ff952..26a26ddfad9 100644 --- a/src/main/java/org/cbioportal/persistence/mybatis/MutationMapper.java +++ b/src/main/java/org/cbioportal/persistence/mybatis/MutationMapper.java @@ -1,6 +1,7 @@ package org.cbioportal.persistence.mybatis; import org.cbioportal.model.GeneFilterQuery; +import org.cbioportal.model.GenomicDataCountItem; import org.cbioportal.model.Mutation; import org.cbioportal.model.MutationCountByPosition; import org.cbioportal.model.meta.MutationMeta; @@ -10,21 +11,21 @@ public interface MutationMapper { List getMutationsBySampleListId(String molecularProfileId, String sampleListId, List entrezGeneIds, - Boolean snpOnly, String projection, Integer limit, Integer offset, + boolean snpOnly, String projection, Integer limit, Integer offset, String sortBy, String direction); MutationMeta getMetaMutationsBySampleListId(String molecularProfileId, String sampleListId, - List entrezGeneIds, Boolean snpOnly); + List entrezGeneIds, boolean snpOnly); List getMutationsInMultipleMolecularProfiles(List molecularProfileIds, List sampleIds, - List entrezGeneIds, Boolean snpOnly, + List entrezGeneIds, boolean snpOnly, String projection, Integer limit, Integer offset, String sortBy, String direction); List getMutationsInMultipleMolecularProfilesByGeneQueries(List molecularProfileIds, List sampleIds, - Boolean snpOnly, + boolean snpOnly, String projection, Integer limit, Integer offset, @@ -33,12 +34,14 @@ List getMutationsInMultipleMolecularProfilesByGeneQueries(List List geneQueries); MutationMeta getMetaMutationsInMultipleMolecularProfiles(List molecularProfileIds, List sampleIds, - List entrezGeneIds, Boolean snpOnly); + List entrezGeneIds, boolean snpOnly); MutationMeta getMetaMutationsBySampleIds(String molecularProfileId, List sampleIds, - List entrezGeneIds, Boolean snpOnly); + List entrezGeneIds, boolean snpOnly); MutationCountByPosition getMutationCountByPosition(Integer entrezGeneId, Integer proteinPosStart, Integer proteinPosEnd); + GenomicDataCountItem getMutationCountsByType(List molecularProfileIds, List sampleIds, + List entrezGeneIds, boolean snpOnly, String profileType); } diff --git a/src/main/java/org/cbioportal/persistence/mybatis/MutationMyBatisRepository.java b/src/main/java/org/cbioportal/persistence/mybatis/MutationMyBatisRepository.java index 6adc902dd9e..f5eb82ac1fe 100644 --- a/src/main/java/org/cbioportal/persistence/mybatis/MutationMyBatisRepository.java +++ b/src/main/java/org/cbioportal/persistence/mybatis/MutationMyBatisRepository.java @@ -1,6 +1,7 @@ package org.cbioportal.persistence.mybatis; import org.cbioportal.model.GeneFilterQuery; +import org.cbioportal.model.GenomicDataCountItem; import org.cbioportal.model.Mutation; import org.cbioportal.model.MutationCountByPosition; import org.cbioportal.model.meta.MutationMeta; @@ -25,7 +26,7 @@ public class MutationMyBatisRepository implements MutationRepository { @Override public List getMutationsInMolecularProfileBySampleListId(String molecularProfileId, String sampleListId, - List entrezGeneIds, Boolean snpOnly, + List entrezGeneIds, boolean snpOnly, String projection, Integer pageSize, Integer pageNumber, String sortBy, String direction) { @@ -38,7 +39,7 @@ public List getMutationsInMolecularProfileBySampleListId(String molecu public MutationMeta getMetaMutationsInMolecularProfileBySampleListId(String molecularProfileId, String sampleListId, List entrezGeneIds) { - return mutationMapper.getMetaMutationsBySampleListId(molecularProfileId, sampleListId, entrezGeneIds, null); + return mutationMapper.getMetaMutationsBySampleListId(molecularProfileId, sampleListId, entrezGeneIds, false); } @Override @@ -55,7 +56,7 @@ public List getMutationsInMultipleMolecularProfiles(List molec Arrays.asList(entry.getKey()), new ArrayList<>(entry.getValue()), entrezGeneIds, - null, + false, projection, pageSize, offsetCalculator.calculate(pageSize, pageNumber), @@ -83,7 +84,7 @@ public List getMutationsInMultipleMolecularProfilesByGeneQueries(List< .flatMap(entry -> mutationMapper.getMutationsInMultipleMolecularProfilesByGeneQueries( Arrays.asList(entry.getKey()), new ArrayList<>(entry.getValue()), - null, + false, projection, pageSize, offsetCalculator.calculate(pageSize, pageNumber), @@ -99,12 +100,12 @@ public MutationMeta getMetaMutationsInMultipleMolecularProfiles(List mol List entrezGeneIds) { return mutationMapper.getMetaMutationsInMultipleMolecularProfiles(molecularProfileIds, sampleIds, entrezGeneIds, - null); + false); } @Override public List fetchMutationsInMolecularProfile(String molecularProfileId, List sampleIds, - List entrezGeneIds, Boolean snpOnly, + List entrezGeneIds, boolean snpOnly, String projection, Integer pageSize, Integer pageNumber, String sortBy, String direction) { @@ -124,7 +125,7 @@ public List fetchMutationsInMolecularProfile(String molecularProfileId public MutationMeta fetchMetaMutationsInMolecularProfile(String molecularProfileId, List sampleIds, List entrezGeneIds) { - return mutationMapper.getMetaMutationsBySampleIds(molecularProfileId, sampleIds, entrezGeneIds, null); + return mutationMapper.getMetaMutationsBySampleIds(molecularProfileId, sampleIds, entrezGeneIds, false); } @Override @@ -134,4 +135,10 @@ public MutationCountByPosition getMutationCountByPosition(Integer entrezGeneId, return mutationMapper.getMutationCountByPosition(entrezGeneId, proteinPosStart, proteinPosEnd); } + @Override + public GenomicDataCountItem getMutationCountsByType(List molecularProfileIds, List sampleIds, + List entrezGeneIds, String profileType) { + return mutationMapper.getMutationCountsByType(molecularProfileIds, sampleIds, entrezGeneIds, + false, profileType); + } } diff --git a/src/main/java/org/cbioportal/persistence/mybatis/StudyMyBatisRepository.java b/src/main/java/org/cbioportal/persistence/mybatis/StudyMyBatisRepository.java index 4821f500558..6a508a81439 100644 --- a/src/main/java/org/cbioportal/persistence/mybatis/StudyMyBatisRepository.java +++ b/src/main/java/org/cbioportal/persistence/mybatis/StudyMyBatisRepository.java @@ -8,6 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; +import java.util.ArrayList; import java.util.List; @Repository @@ -55,7 +56,9 @@ public CancerStudyTags getTags(String studyId) { @Override public List getTagsForMultipleStudies(List studyIds) { - + if (studyIds == null || studyIds.isEmpty()) { + return new ArrayList<>(); + } return studyMapper.getTagsForMultipleStudies(studyIds); } } diff --git a/src/main/java/org/cbioportal/persistence/mybatis/config/PersistenceConfig.java b/src/main/java/org/cbioportal/persistence/mybatis/config/PersistenceConfig.java index 86a604875a5..933be27cc4a 100644 --- a/src/main/java/org/cbioportal/persistence/mybatis/config/PersistenceConfig.java +++ b/src/main/java/org/cbioportal/persistence/mybatis/config/PersistenceConfig.java @@ -1,17 +1,16 @@ package org.cbioportal.persistence.mybatis.config; -import org.apache.ibatis.session.SqlSessionFactory; import org.cbioportal.model.Sample; import org.cbioportal.persistence.mybatis.typehandler.SampleTypeTypeHandler; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.io.Resource; -import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import javax.sql.DataSource; +import java.io.IOException; @Configuration @@ -32,14 +31,12 @@ public void customize(org.apache.ibatis.session.Configuration configuration) { } @Bean - public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) throws Exception { + public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource, ApplicationContext applicationContext) throws IOException { SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(dataSource); - // Specify the location of your mapper XML files in the 'mappers' directory - Resource[] resources = new PathMatchingResourcePatternResolver() - .getResources("classpath:org/cbioportal/persistence/mybatis/*.xml"); - - sessionFactory.setMapperLocations(resources); + sessionFactory.setMapperLocations( + applicationContext.getResources("classpath:org/cbioportal/persistence/mybatis/*.xml") + ); sessionFactory.setTypeHandlers(new SampleTypeTypeHandler()); return sessionFactory; } diff --git a/src/main/java/org/cbioportal/properties/PortalProperties.java b/src/main/java/org/cbioportal/properties/PortalProperties.java index fbb8f3a876f..298c343a7be 100644 --- a/src/main/java/org/cbioportal/properties/PortalProperties.java +++ b/src/main/java/org/cbioportal/properties/PortalProperties.java @@ -11,7 +11,7 @@ public class PortalProperties { @AllowedValues(values = {"false", "saml", "oauth2", - "optional_oauth2", "social_oauth"}) + "optional_oauth2", "saml_plus_basic"}) private String authenticate; public void setAuthenticate(String authenticate) { diff --git a/src/main/java/org/cbioportal/proxy/ProxyController.java b/src/main/java/org/cbioportal/proxy/ProxyController.java index 36e670c3ca9..00ad2e500b4 100644 --- a/src/main/java/org/cbioportal/proxy/ProxyController.java +++ b/src/main/java/org/cbioportal/proxy/ProxyController.java @@ -2,25 +2,36 @@ import jakarta.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.cbioportal.proxy.util.CheckDarwinAccessUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.*; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.security.core.Authentication; import org.springframework.util.ObjectUtils; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; - -import java.io.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.util.Properties; +import java.util.regex.Pattern; // TODO Consider creating separate DispatcherServlets as in the original web.xml // See: https://stackoverflow.com/a/30686733/11651683 @@ -29,9 +40,6 @@ @RequestMapping("/proxy") public class ProxyController { private static final String DEFAULT_ONCOKB_URL = "https://public.api.oncokb.org/api/v1"; - private Properties properties; - - private Logger LOG = LoggerFactory.getLogger(ProxyController.class); @Autowired private Monkifier monkifier; @@ -44,6 +52,19 @@ public class ProxyController { @Value("${show.oncokb:false}") private Boolean showOncokb; + + @Value("${darwin.auth_url:}") + private String darwinAuthUrl; + + @Value("${ddp.response_url:}") + private String ddpResponseUrl; + + @Value("${cis.user:}") + private String cisUser; + + @Value("${darwin.regex:Test}") + private String darwinRegex; + @RequestMapping("/**") public String proxy(@RequestBody(required = false) String body, HttpMethod method, HttpServletRequest request) @@ -53,7 +74,7 @@ public String proxy(@RequestBody(required = false) String body, HttpMethod metho // TODO when reimplemeting different dispatcherservlets with different context roots // reset this to 'String requestPathInfo = request.getPathInfo();' String requestPathInfo = request.getPathInfo() == null? request.getServletPath() : request.getPathInfo(); - + requestPathInfo = requestPathInfo.replace("proxy/", ""); return exchangeData(body, buildUri(requestPathInfo, request.getQueryString(), false), method, @@ -172,6 +193,13 @@ public String proxyOncokb(@RequestBody(required = false) String body, HttpMethod httpHeaders, String.class).getBody(); } + + @GetMapping("/checkDarwinAccess") + public ResponseEntity checkDarwinAccess(HttpServletRequest request, Authentication authentication) { + String user = authentication != null ? authentication.getName(): "anonymousUser"; + String darwinResponse = CheckDarwinAccessUtil.checkAccess(request, darwinAuthUrl, ddpResponseUrl, cisUser, Pattern.compile(darwinRegex), user); + return new ResponseEntity<>(darwinResponse, HttpStatus.OK); + } private HttpHeaders initHeaders(HttpServletRequest request) { HttpHeaders httpHeaders = new HttpHeaders(); diff --git a/src/main/java/org/cbioportal/proxy/util/CheckDarwinAccessUtil.java b/src/main/java/org/cbioportal/proxy/util/CheckDarwinAccessUtil.java new file mode 100644 index 00000000000..be9dc2b1152 --- /dev/null +++ b/src/main/java/org/cbioportal/proxy/util/CheckDarwinAccessUtil.java @@ -0,0 +1,243 @@ +package org.cbioportal.proxy.util; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.servlet.http.HttpServletRequest; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.web.client.RestTemplate; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.regex.Pattern; + +public final class CheckDarwinAccessUtil { + private static final Logger logger = LoggerFactory.getLogger(CheckDarwinAccessUtil.class); + + private static final String DDP_INFO_ENDPOINT = "/info"; + public static final String SAMPLE_ID = "sample_id"; + public static final String PATIENT_ID = "case_id"; + + private CheckDarwinAccessUtil() { + throw new IllegalStateException("Utility class"); + } + + public static String checkAccess(HttpServletRequest request, String darwinAuthUrl, String ddpResponseUrl, String cisUser, Pattern sampleIdRegex, String user) { + logger.debug("checkDarwinAccess Requested"); + if (!existsDarwinProperties(darwinAuthUrl, ddpResponseUrl, cisUser, sampleIdRegex)) { + logger.debug("Darwin Properties do not exists"); + return ""; + } + // if sample id does not match regex or username matches cis username then return empty string + String userName = user.split("@")[0]; + String darwinResponse = ""; + try { + String[] sampleIds = request.getParameter(SAMPLE_ID).split(","); + if (sampleIdRegex.matcher(sampleIds[0]).find() && !cisUser.equals(userName)) { + String patientId = request.getParameter(PATIENT_ID); + darwinResponse = getResponse(userName, patientId, darwinAuthUrl, ddpResponseUrl); + } + } catch (NullPointerException ignored) { + logger.debug("Error Sending CheckDarwinAccess API"); + } + + return darwinResponse; + } + + public static String getResponse(String userName, String patientId, String darwinAuthUrl, String ddpResponseUrl) { + RestTemplate restTemplate = new RestTemplate(); + HttpEntity> requestEntity = getRequestEntity(userName, patientId); + ResponseEntity responseEntity = restTemplate.exchange(darwinAuthUrl, HttpMethod.POST, requestEntity, DarwinAccess.class); + String darwinResponse = Objects.requireNonNull(responseEntity.getBody()).getDarwinAuthResponse(); + String deidentificationId = Objects.requireNonNull(responseEntity.getBody()).getDeidentificationId(); + if (!darwinResponse.equals("valid")) { + return ""; + } + if (deidentificationId.isEmpty()) { + return ""; + } + // construct URL + return ddpResponseUrl + deidentificationId + DDP_INFO_ENDPOINT; + } + + private static HttpEntity> getRequestEntity(String userName, String patientId) { + LinkedMultiValueMap map = new LinkedMultiValueMap<>(); + map.add("p_userName", userName); + map.add("p_dmp_pid", patientId); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + return new HttpEntity<>(map, headers); + } + + public static boolean existsDarwinProperties(String darwinAuthUrl, String ddpResponseUrl, String cisUser, Pattern sampleIdRegex) { + return (!darwinAuthUrl.isEmpty() && !ddpResponseUrl.isEmpty() && !cisUser.isEmpty() && !sampleIdRegex.toString().isEmpty()); + } + + + public static class DarwinAccess { + /** + * (Required) + **/ + @JsonProperty("darwinAuthResponse") + private String darwinAuthResponse; + /** + * (Required) + **/ + @JsonProperty("p_userName") + private String pUserName; + /** + * (Required) + **/ + @JsonProperty("p_dmp_pid") + private String pDmpPid; + /** + * (Required) + **/ + @JsonProperty("deidentification_id") + private String deidentificationId; + + @JsonIgnore + private Map additionalProperties = new HashMap<>(); + + /** + * No args constructor for use in serialization + **/ + public DarwinAccess() { + } + + /** + * + **/ + public DarwinAccess(String darwinAuthResponse, String pUserName, String pDmpPid, String deidentificationId) { + this.darwinAuthResponse = darwinAuthResponse; + this.pUserName = pUserName; + this.pDmpPid = pDmpPid; + this.deidentificationId = deidentificationId; + } + + /** + * (Required) + * + * @return The darwinAuthResponse + **/ + @JsonProperty("darwinAuthResponse") + public String getDarwinAuthResponse() { + return darwinAuthResponse; + } + + /** + * (Required) + * + * @param darwinAuthResponse The Darwin authorization response + **/ + @JsonProperty("darwinAuthResponse") + public void setDarwinAuthResponse(String darwinAuthResponse) { + this.darwinAuthResponse = darwinAuthResponse; + } + + public DarwinAccess withDarwinAuthResponse(String darwinAuthResponse) { + this.darwinAuthResponse = darwinAuthResponse; + return this; + } + + /** + * (Required) + * + * @return The p_userName + **/ + @JsonProperty("p_userName") + public String getPUserName() { + return pUserName; + } + + /** + * (Required) + * + * @param pUserName The p_userName + **/ + @JsonProperty("p_userName") + public void setPUserName(String pUserName) { + this.pUserName = pUserName; + } + + public DarwinAccess withPUserName(String pUserName) { + this.pUserName = pUserName; + return this; + } + + /** + * (Required) + * + * @return The p_dmp_pid + **/ + @JsonProperty("p_dmp_pid") + public String getPDmpPid() { + return pDmpPid; + } + + /** + * (Required) + * + * @param pDmpPid The p_dmp_pid + **/ + @JsonProperty("p_dmp_pid") + public void setPDmpPid(String pDmpPid) { + this.pDmpPid = pDmpPid; + } + + /** + * (Required) + * + * @return The deidentification_id + **/ + @JsonProperty("deidentification_id") + public String getDeidentificationId() { + return deidentificationId; + } + + /** + * (Required) + * + * @param deidentificationId The deidentification_id + **/ + @JsonProperty("deidentification_id") + public void setDeidentificationId(String deidentificationId) { + this.deidentificationId = deidentificationId; + } + + public DarwinAccess withPDmpPid(String pDmpPid) { + this.pDmpPid = pDmpPid; + return this; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + + public DarwinAccess withAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + return this; + } + } +} \ No newline at end of file diff --git a/src/main/java/org/cbioportal/security/CancerStudyPermissionEvaluator.java b/src/main/java/org/cbioportal/security/CancerStudyPermissionEvaluator.java index 7947c204e5d..e2d3c354581 100644 --- a/src/main/java/org/cbioportal/security/CancerStudyPermissionEvaluator.java +++ b/src/main/java/org/cbioportal/security/CancerStudyPermissionEvaluator.java @@ -283,7 +283,10 @@ private boolean hasAccessToCancerStudy(Authentication authentication, CancerStud } // check if user is in study groups // performance now takes precedence over group accuracy (minimal risk to caching cancer study groups) - Set groups = new HashSet(Arrays.asList(cancerStudy.getGroups().split(";"))); + // need to filter out empty groups, this can cause issue if grantedAuthorities and groups both contain empty string + Set groups = Arrays.stream(cancerStudy.getGroups().split(";")) + .filter(g -> !g.isEmpty()) + .collect(Collectors.toSet()); if (!Collections.disjoint(groups, grantedAuthorities)) { if (log.isDebugEnabled()) { log.debug("hasAccessToCancerStudy(), user has access by groups return true"); @@ -363,9 +366,11 @@ private boolean hasAccessToSampleLists(Authentication authentication, Collection private Set getGrantedAuthorities(Authentication authentication) { String appName = getAppName().toUpperCase(); + // need to filter out empty authorities, this can cause issue if grantedAuthorities and groups both contain empty string Set allAuthorities = AuthorityUtils.authorityListToSet(authentication.getAuthorities()) .stream() .map(authority -> authority.replaceAll("^ROLE_", "")) + .filter(a -> !a.isEmpty()) .collect(Collectors.toSet()); Set grantedAuthorities = new HashSet<>(); if (filterGroupsByAppName()) { diff --git a/src/main/java/org/cbioportal/security/CustomJwtGrantedAuthoritiesConverter.java b/src/main/java/org/cbioportal/security/CustomJwtGrantedAuthoritiesConverter.java deleted file mode 100644 index 0d3f8f9b06c..00000000000 --- a/src/main/java/org/cbioportal/security/CustomJwtGrantedAuthoritiesConverter.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.cbioportal.security; - -import org.cbioportal.security.util.GrantedAuthorityUtil; -import org.cbioportal.security.util.ClaimRoleExtractorUtil; -import org.springframework.core.convert.converter.Converter; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.oauth2.jwt.Jwt; - -import java.util.Collection; -import java.util.Objects; - -/** - * Custom JWT GrantedAuthorities Converter to extract roles from JWT token. - * Claims should equal resource_access:clientId:roles - */ -public class CustomJwtGrantedAuthoritiesConverter implements Converter> { - private static final String DEFAULT_CLIENT_ID = "cbioportal"; - - private String jwtRolePathClientId; - - @Override - public Collection convert(Jwt jwt) { - return GrantedAuthorityUtil.generateGrantedAuthoritiesFromRoles(getAuthorities(jwt)); - } - - private Collection getAuthorities(Jwt jwt) { - return ClaimRoleExtractorUtil.extractClientRoles(this.getJwtRolePathClientId(), jwt.getClaims()); - } - - private String getJwtRolePathClientId() { - return Objects.isNull(jwtRolePathClientId) ? DEFAULT_CLIENT_ID : jwtRolePathClientId; - } - - public void setClientId(String clientId) { - this.jwtRolePathClientId = clientId; - } -} diff --git a/src/main/java/org/cbioportal/security/basic/BasicRestfulAuthenticationSuccessHandler.java b/src/main/java/org/cbioportal/security/basic/BasicRestfulAuthenticationSuccessHandler.java new file mode 100644 index 00000000000..9291f27abcd --- /dev/null +++ b/src/main/java/org/cbioportal/security/basic/BasicRestfulAuthenticationSuccessHandler.java @@ -0,0 +1,36 @@ +package org.cbioportal.security.basic; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.context.SecurityContextHolderStrategy; +import org.springframework.security.web.DefaultRedirectStrategy; +import org.springframework.security.web.RedirectStrategy; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.springframework.security.web.context.HttpSessionSecurityContextRepository; +import org.springframework.security.web.context.SecurityContextRepository; + +import java.io.IOException; + +public class BasicRestfulAuthenticationSuccessHandler implements AuthenticationSuccessHandler { + + private final SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder.getContextHolderStrategy(); + private final SecurityContextRepository securityContextRepository = new HttpSessionSecurityContextRepository(); + private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); + @Override + public void onAuthenticationSuccess(HttpServletRequest request, + HttpServletResponse response, Authentication authentication) throws IOException { + HttpSession session = request.getSession(true); + session.setAttribute("user_id", request.getParameter("user_id")); + SecurityContext context = this.securityContextHolderStrategy.createEmptyContext(); + context.setAuthentication(authentication); + this.securityContextHolderStrategy.setContext(context); + this.securityContextRepository.saveContext(context, request, response); + redirectStrategy.sendRedirect(request, response, "/restful_login"); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/cbioportal/security/config/ApiSecurityConfig.java b/src/main/java/org/cbioportal/security/config/ApiSecurityConfig.java new file mode 100644 index 00000000000..51f8e07e99d --- /dev/null +++ b/src/main/java/org/cbioportal/security/config/ApiSecurityConfig.java @@ -0,0 +1,98 @@ +package org.cbioportal.security.config; + +import org.cbioportal.security.token.RestAuthenticationEntryPoint; +import org.cbioportal.security.token.TokenAuthenticationFilter; +import org.cbioportal.security.token.TokenAuthenticationSuccessHandler; +import org.cbioportal.service.DataAccessTokenService; +import org.cbioportal.utils.config.annotation.ConditionalOnProperty; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpStatus; +import org.springframework.lang.Nullable; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.HttpStatusEntryPoint; +import org.springframework.security.web.context.SecurityContextHolderFilter; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +@Configuration +@ConditionalOnProperty(name = "authenticate", havingValue = {"false", "noauthsessionservice", "optional_oauth2"}, isNot = true) +public class ApiSecurityConfig { + + // Add security filter chains that handle calls to the API endpoints. + // Different chains are added for the '/api' and legacy '/webservice.do' paths. + // Both are able to handle API tokens provided in the request. + // see: "Creating and Customizing Filter Chains" @ https://spring.io/guides/topicals/spring-security-architecture + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http, @Nullable DataAccessTokenService tokenService) throws Exception { + http.csrf(AbstractHttpConfigurer::disable) + // This filter chain only grabs requests to the '/api' path. + .securityMatcher("/api/**", "/webservice.do") + .authorizeHttpRequests(authorize -> authorize + .requestMatchers( + "/api/swagger-resources/**", + "/api/swagger-ui.html", + "/api/health", + "/api/cache/**").permitAll() + .anyRequest().authenticated() + ) + .sessionManagement(sessionManagement -> sessionManagement.sessionFixation().migrateSession()) + .exceptionHandling(eh -> + eh.defaultAuthenticationEntryPointFor( + new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED), AntPathRequestMatcher.antMatcher("/api/**") + ) + ); + // When dat.method is not 'none' and a tokenService bean is present, + // the apiTokenAuthenticationFilter is added to the filter chain. + if (tokenService != null) { + http.apply(ApiTokenFilterDsl.tokenFilterDsl(tokenService)); + } + return http.build(); + } + + @Autowired + public void buildAuthenticationManager(AuthenticationManagerBuilder authenticationManagerBuilder, + @Nullable AuthenticationProvider... authenticationProviders) { + if (authenticationProviders != null) { + for (AuthenticationProvider authenticationProvider : authenticationProviders) { + authenticationManagerBuilder.authenticationProvider(authenticationProvider); + } + } + } + + @Bean + public RestAuthenticationEntryPoint restAuthenticationEntryPoint() { + return new RestAuthenticationEntryPoint(); + } + +} + + +class ApiTokenFilterDsl extends AbstractHttpConfigurer { + + private final DataAccessTokenService tokenService; + + public ApiTokenFilterDsl(DataAccessTokenService tokenService) { + this.tokenService = tokenService; + } + + @Override + public void configure(HttpSecurity http) { + AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class); + TokenAuthenticationSuccessHandler tokenAuthenticationSuccessHandler = new TokenAuthenticationSuccessHandler(); + TokenAuthenticationFilter filter = new TokenAuthenticationFilter("/**", authenticationManager, tokenService); + filter.setAuthenticationSuccessHandler(tokenAuthenticationSuccessHandler); + http.addFilterAfter(filter, SecurityContextHolderFilter.class); + } + + public static ApiTokenFilterDsl tokenFilterDsl(DataAccessTokenService tokenService) { + return new ApiTokenFilterDsl(tokenService); + } + +} diff --git a/src/main/java/org/cbioportal/security/config/AutoconfigureExcludeConfig.java b/src/main/java/org/cbioportal/security/config/AutoconfigureExcludeConfig.java new file mode 100644 index 00000000000..5c14beb51e6 --- /dev/null +++ b/src/main/java/org/cbioportal/security/config/AutoconfigureExcludeConfig.java @@ -0,0 +1,38 @@ +package org.cbioportal.security.config; + +import org.cbioportal.utils.config.annotation.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; +import org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration; +import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration; +import org.springframework.context.annotation.Configuration; + +// Conditionally disable autoconfguration for Spring Boot components. +public class AutoconfigureExcludeConfig { + + private AutoconfigureExcludeConfig() {} + + @Configuration + @ConditionalOnProperty(name = "authenticate", havingValue = {"saml", "oauth2", "optional_oauth2","saml_plus_basic"}, isNot = true) + @EnableAutoConfiguration(exclude={OAuth2ClientAutoConfiguration.class, Saml2RelyingPartyAutoConfiguration.class}) + public static class ExcludeAll {} + + @Configuration + @ConditionalOnExpression("{'saml','saml_plus_basic'}.contains('${authenticate}')") + @EnableAutoConfiguration(exclude=OAuth2ClientAutoConfiguration.class) + public static class Saml {} + + @Configuration + @ConditionalOnProperty(name = "authenticate", havingValue = "oauth2") + @EnableAutoConfiguration(exclude=Saml2RelyingPartyAutoConfiguration.class) + public static class OAuth2 {} + + @Configuration + @ConditionalOnExpression( + "T(org.apache.commons.lang3.StringUtils).isEmpty('${spring.session.store-type:}')" + ) + @EnableAutoConfiguration(exclude=RedisAutoConfiguration.class) + public static class Redis {} + +} diff --git a/src/main/java/org/cbioportal/security/config/CorsConfig.java b/src/main/java/org/cbioportal/security/config/CorsConfig.java new file mode 100644 index 00000000000..cd92394da49 --- /dev/null +++ b/src/main/java/org/cbioportal/security/config/CorsConfig.java @@ -0,0 +1,37 @@ +package org.cbioportal.security.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; + +import java.util.List; + +@Configuration +@EnableWebSecurity +public class CorsConfig { + @Value("${security.cors.allowed-origins:}") + private String allowedOrigins; + + @Bean + CorsConfigurationSource corsConfigurationSource() { + List parsedAllowedOrigins = List.of(allowedOrigins.split(",")); + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + if ( parsedAllowedOrigins.isEmpty()) { + return source; + } + + CorsConfiguration configuration = new CorsConfiguration(); + configuration.setAllowedOrigins(parsedAllowedOrigins); + configuration.setAllowedMethods(List.of("GET","POST", "HEAD","OPTIONS")); + configuration.setAllowedHeaders(List.of("user-agent", "Origin", "Accept", "X-Requested-With","Content-Type", + "Access-Control-Request-Method","Access-Control-Request-Headers","Content-Encoding", + "X-Proxy-User-Agreement", "x-current-url")); + configuration.setExposedHeaders(List.of("total-count", "sample-count")); + source.registerCorsConfiguration("/**", configuration); + return source; + } +} diff --git a/src/main/java/org/cbioportal/security/config/CustomOAuth2AuthorizationConfig.java b/src/main/java/org/cbioportal/security/config/CustomOAuth2AuthorizationConfig.java new file mode 100644 index 00000000000..7929fdce39f --- /dev/null +++ b/src/main/java/org/cbioportal/security/config/CustomOAuth2AuthorizationConfig.java @@ -0,0 +1,78 @@ +package org.cbioportal.security.config; + +import org.cbioportal.model.User; +import org.cbioportal.model.UserAuthorities; +import org.cbioportal.persistence.SecurityRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest; +import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService; +import org.springframework.security.oauth2.client.userinfo.OAuth2UserService; +import org.springframework.security.oauth2.core.OAuth2AuthenticationException; +import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; +import org.springframework.security.oauth2.core.oidc.user.OidcUser; + +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +@Configuration +@EnableWebSecurity +@ConditionalOnProperty(value = "authorization", havingValue = "true") +public class CustomOAuth2AuthorizationConfig { + Logger log = LoggerFactory.getLogger(CustomOAuth2AuthorizationConfig.class); + + private final SecurityRepository securityRepository; + + private static final String NAME_ATTRIBUTE_KEY = "email"; + + @Autowired + public CustomOAuth2AuthorizationConfig(SecurityRepository securityRepository) { + this.securityRepository = securityRepository; + } + + @Bean + public OAuth2UserService oidcUserService() { + final OidcUserService delegate = new OidcUserService(); + + return userRequest -> { + log.debug("Custom OAuth2 Authorization Enabled"); + + // Delegate to the default implementation for loading a user + OidcUser oidcUser = delegate.loadUser(userRequest); + + var authenticatedPortalUser = loadPortalUser(oidcUser.getEmail()); + if (Objects.isNull(authenticatedPortalUser.cbioUser) || !authenticatedPortalUser.cbioUser.isEnabled()) { + log.debug("User: {} either not in db or not authorized", oidcUser.getEmail()); + throw new OAuth2AuthenticationException("user not authorized"); + } + Set mappedAuthorities = authenticatedPortalUser.authorities; + oidcUser = new DefaultOidcUser(mappedAuthorities, oidcUser.getIdToken(), oidcUser.getUserInfo(), NAME_ATTRIBUTE_KEY); + return oidcUser; + }; + } + + private AuthenticatedPortalUser loadPortalUser(String email) { + Set mappedAuthorities = new HashSet<>(); + User cbioUser = securityRepository.getPortalUser(email); + if (!Objects.isNull(cbioUser)) { + UserAuthorities authorities = securityRepository.getPortalUserAuthorities(email); + if (!Objects.isNull(authorities)) { + mappedAuthorities.addAll(AuthorityUtils.createAuthorityList(authorities.getAuthorities())); + } + } + return new AuthenticatedPortalUser(cbioUser, mappedAuthorities); + } + + record AuthenticatedPortalUser(User cbioUser, Set authorities) { + + } + +} \ No newline at end of file diff --git a/src/main/java/org/cbioportal/security/config/MethodSecurityConfig.java b/src/main/java/org/cbioportal/security/config/MethodSecurityConfig.java index f347bf832e9..1d9d6013568 100644 --- a/src/main/java/org/cbioportal/security/config/MethodSecurityConfig.java +++ b/src/main/java/org/cbioportal/security/config/MethodSecurityConfig.java @@ -3,10 +3,8 @@ import org.cbioportal.persistence.cachemaputil.CacheMapUtil; import org.cbioportal.security.CancerStudyPermissionEvaluator; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler; @@ -15,9 +13,8 @@ @Configuration @EnableMethodSecurity(prePostEnabled = true) -@ConditionalOnExpression("{'oauth2','saml','optional_oauth2'}.contains('${authenticate}')") -//TODO: Potentially Delete after import pipeline fixed -@ConditionalOnProperty(name = "security.method_authorization_enabled", havingValue = "true") +// We are allowing users to enable method_authorization if optional_oauth2 is selected +@ConditionalOnExpression("{'oauth2','saml', 'saml_plus_basic'}.contains('${authenticate}') or ('optional_oauth2' eq '${authenticate}' and 'true' eq '${security.method_authorization_enabled}')") public class MethodSecurityConfig { @Value("${app.name:}") private String appName; @@ -28,7 +25,6 @@ public class MethodSecurityConfig { @Value("${always_show_study_group:}") private String alwaysShowCancerStudyGroup; - @Qualifier("staticRefCacheMapUtil") @Autowired private CacheMapUtil cacheMapUtil; diff --git a/src/main/java/org/cbioportal/security/config/NoSecurityConfig.java b/src/main/java/org/cbioportal/security/config/NoSecurityConfig.java index 8e7741a81db..42f49c96cd3 100644 --- a/src/main/java/org/cbioportal/security/config/NoSecurityConfig.java +++ b/src/main/java/org/cbioportal/security/config/NoSecurityConfig.java @@ -3,6 +3,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; @@ -14,11 +15,13 @@ public class NoSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{ - return http.authorizeHttpRequests(auth -> auth + return http + .cors(Customizer.withDefaults()) + .csrf(AbstractHttpConfigurer::disable) + .authorizeHttpRequests(auth -> auth .requestMatchers("/").permitAll() .anyRequest().permitAll() ) - .csrf(AbstractHttpConfigurer::disable) .build(); } } \ No newline at end of file diff --git a/src/main/java/org/cbioportal/security/config/OAuth2SecurityConfig.java b/src/main/java/org/cbioportal/security/config/OAuth2SecurityConfig.java index 4a8801029a0..c13c5226586 100644 --- a/src/main/java/org/cbioportal/security/config/OAuth2SecurityConfig.java +++ b/src/main/java/org/cbioportal/security/config/OAuth2SecurityConfig.java @@ -1,110 +1,113 @@ package org.cbioportal.security.config; -import org.cbioportal.security.CustomJwtGrantedAuthoritiesConverter; import org.cbioportal.security.util.ClaimRoleExtractorUtil; import org.cbioportal.security.util.GrantedAuthorityUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; -import org.springframework.http.HttpStatus; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; -import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer; import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; +import org.springframework.security.oauth2.client.oidc.web.logout.OidcClientInitiatedLogoutSuccessHandler; +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.core.oidc.user.OidcUserAuthority; import org.springframework.security.oauth2.core.user.OAuth2UserAuthority; -import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; import org.springframework.security.web.SecurityFilterChain; -import org.springframework.security.web.authentication.HttpStatusEntryPoint; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.stream.Collectors; @Configuration -@EnableWebSecurity // add new chain after api-filter chain (at position -2), but before the default fallback chain @Order(SecurityProperties.BASIC_AUTH_ORDER - 1) +@ConditionalOnProperty(value = "authenticate", havingValue = "oauth2") public class OAuth2SecurityConfig { + private static final Logger log = LoggerFactory.getLogger(OAuth2SecurityConfig.class); + + + @Value("${spring.security.oauth2.client.jwt-roles-path:resource_access::cbioportal::roles}") + private String jwtRolesPath; - @Value("${spring.security.oauth2.roles-path.client-id:}") - private String clientId; - - @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri:}") - private String jwtResourceServerUri; - - @Bean - @ConditionalOnProperty(value = "authenticate", havingValue = "oauth2") - public SecurityFilterChain oAuth2filterChain(HttpSecurity http) throws Exception { + private static final String LOGIN_URL = "/login"; - http.authorizeHttpRequests(auth -> - auth.requestMatchers("/api/health", "/login", "/images/**").permitAll() - .anyRequest().authenticated()) - .oauth2Login(oauth -> oauth.loginPage("/login")) - .logout((logout) -> logout.logoutSuccessUrl("/login?logout_success")) - .exceptionHandling(eh -> - eh.defaultAuthenticationEntryPointFor(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED), AntPathRequestMatcher.antMatcher("/api/**"))) - .csrf(AbstractHttpConfigurer::disable); - - if(!Objects.isNull(this.jwtResourceServerUri) && !this.jwtResourceServerUri.isEmpty()) { - http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt); - } + @Bean + public SecurityFilterChain filterChain(HttpSecurity http, ClientRegistrationRepository clientRegistrationRepository) throws Exception { + http.csrf(AbstractHttpConfigurer::disable) + .cors(Customizer.withDefaults()) + .authorizeHttpRequests(authorize -> + authorize + .requestMatchers("/api/health", LOGIN_URL, "/images/**").permitAll() + .anyRequest().authenticated() + ) + .oauth2Login(login -> + login + .loginPage(LOGIN_URL) + .userInfoEndpoint(userInfo -> + userInfo.userAuthoritiesMapper(userAuthoritiesMapper()) + ) + .failureUrl(LOGIN_URL + "?logout_failure") + ) + .logout(logout -> logout + .logoutSuccessHandler(oidcLogoutSuccessHandler(clientRegistrationRepository)) + ); return http.build(); } - @Bean - @ConditionalOnProperty(value = "authenticate", havingValue = "optional_oauth2") - public SecurityFilterChain optionalOAuth2filterChain(HttpSecurity http) throws Exception { - return http - .oauth2Login(oauth -> oauth.loginPage("/login")) - .authorizeHttpRequests(auth -> auth - .requestMatchers("/").permitAll() - .anyRequest().permitAll()) - .csrf(AbstractHttpConfigurer::disable) - .logout((logout) -> logout.logoutSuccessUrl("/")) - .build(); - } - @Bean - public GrantedAuthoritiesMapper userAuthoritiesMapper() { + private GrantedAuthoritiesMapper userAuthoritiesMapper() { return (authorities) -> { Set mappedAuthorities = new HashSet<>(); authorities.forEach(authority -> { - Map claims = null; - if (authority instanceof OidcUserAuthority oidcUserAuthority && !Objects.isNull(oidcUserAuthority.getUserInfo())) { - claims = oidcUserAuthority.getUserInfo().getClaims(); - } else if (authority instanceof OAuth2UserAuthority oauth2UserAuthority) { - claims = oauth2UserAuthority.getAttributes(); + List> claims = new ArrayList<>(); + switch (authority) { + case OidcUserAuthority oidcUserAuthority -> { + if(!Objects.isNull(oidcUserAuthority.getUserInfo())) { + claims.add(oidcUserAuthority.getUserInfo().getClaims()); + } + claims.add(oidcUserAuthority.getIdToken().getClaims()); + } + case OAuth2UserAuthority oAuth2UserAuthority -> claims.add(oAuth2UserAuthority.getAttributes()); + case SimpleGrantedAuthority simpleGrantedAuthority -> mappedAuthorities.add(simpleGrantedAuthority); + default -> log.debug("Unsupported UserAuthority Type {}", authority); } - if(!Objects.isNull(claims)) { - var roles = ClaimRoleExtractorUtil.extractClientRoles(this.clientId, claims); - mappedAuthorities.addAll(GrantedAuthorityUtil.generateGrantedAuthoritiesFromRoles(roles)); + if(!claims.isEmpty()) { + var roles = claims.stream() + .filter(claim -> !Objects.isNull(claim)) + .map(claim -> ClaimRoleExtractorUtil.extractClientRoles(claim, jwtRolesPath)) + .flatMap(Collection::stream) + .collect(Collectors.toSet()); + + mappedAuthorities.addAll(GrantedAuthorityUtil.generateGrantedAuthoritiesFromRoles(roles)); } - }); - + }); return mappedAuthorities; }; } - @Bean - public JwtAuthenticationConverter jwtAuthenticationConverter() { - CustomJwtGrantedAuthoritiesConverter grantedAuthoritiesConverter = new CustomJwtGrantedAuthoritiesConverter(); - grantedAuthoritiesConverter.setClientId(this.clientId); - - JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter(); - jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(grantedAuthoritiesConverter); - return jwtAuthenticationConverter; + // See: https://docs.spring.io/spring-security/reference/5.7-SNAPSHOT/servlet/oauth2/login/advanced.html#oauth2login-advanced-oidc-logout + private LogoutSuccessHandler oidcLogoutSuccessHandler(ClientRegistrationRepository clientRegistrationRepository) { + OidcClientInitiatedLogoutSuccessHandler oidcLogoutSuccessHandler = + new OidcClientInitiatedLogoutSuccessHandler(clientRegistrationRepository); + oidcLogoutSuccessHandler.setPostLogoutRedirectUri("{baseUrl}"); + return oidcLogoutSuccessHandler; } } diff --git a/src/main/java/org/cbioportal/security/config/OptionalOAuth2SecurityConfig.java b/src/main/java/org/cbioportal/security/config/OptionalOAuth2SecurityConfig.java new file mode 100644 index 00000000000..248921b2235 --- /dev/null +++ b/src/main/java/org/cbioportal/security/config/OptionalOAuth2SecurityConfig.java @@ -0,0 +1,35 @@ +package org.cbioportal.security.config; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.security.SecurityProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.web.SecurityFilterChain; + + +@Configuration +@EnableWebSecurity +// add new chain after api-filter chain (at position -2), but before the default fallback chain +@Order(SecurityProperties.BASIC_AUTH_ORDER - 1) +@ConditionalOnProperty(value = "authenticate", havingValue = "optional_oauth2") +public class OptionalOAuth2SecurityConfig { + + @Bean + public SecurityFilterChain optionalOAuth2filterChain(HttpSecurity http) throws Exception { + return http + .oauth2Login(oauth -> oauth.loginPage("/login")) + .authorizeHttpRequests(auth -> auth + .requestMatchers("/").permitAll() + .anyRequest().permitAll()) + .cors(Customizer.withDefaults()) + .csrf(AbstractHttpConfigurer::disable) + .logout(logout -> logout.logoutSuccessUrl("/")) + .build(); + } + +} diff --git a/src/main/java/org/cbioportal/security/config/Saml2AndBasicConfig.java b/src/main/java/org/cbioportal/security/config/Saml2AndBasicConfig.java new file mode 100644 index 00000000000..691979c0072 --- /dev/null +++ b/src/main/java/org/cbioportal/security/config/Saml2AndBasicConfig.java @@ -0,0 +1,130 @@ +package org.cbioportal.security.config; + +import org.cbioportal.security.basic.BasicRestfulAuthenticationSuccessHandler; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpStatus; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.HttpStatusEntryPoint; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; +import org.springframework.security.web.context.HttpSessionSecurityContextRepository; +import org.springframework.security.web.context.SecurityContextHolderFilter; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +import java.util.Objects; + +import static org.springframework.security.config.Customizer.withDefaults; + + +@Configuration +@EnableWebSecurity +@ConditionalOnProperty(value = "authenticate", havingValue = "saml_plus_basic") +public class Saml2AndBasicConfig { + private static final String LOGOUT_URL = "/logout"; + private static final String BASIC_LOGOUT_URL = "/j_spring_security_logout"; + + @Value("${basic.username:MOCK_USER}") + private String basicUsername; + + @Value("${basic.password:MOCK_PASSWORD}") + private String basicPassword; + + @Value("${basic.authorities:}") + private String basicAuthorities; + + + @Bean + public SecurityFilterChain samlFilterChain(HttpSecurity http, AuthenticationManagerBuilder authenticationManagerBuilder, + LogoutSuccessHandler logoutSuccessHandler) throws Exception { + buildAuthenticationManager(authenticationManagerBuilder, userDetailsService()); + http.csrf(AbstractHttpConfigurer::disable) + .cors(withDefaults()) + .authorizeHttpRequests(auth -> + auth.requestMatchers("/api/health", "/images/**", "/js/**", "/login").permitAll() + .anyRequest().authenticated()) + .exceptionHandling(eh -> + eh.defaultAuthenticationEntryPointFor( + new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED), AntPathRequestMatcher.antMatcher("/api/**") + ) + ) + .securityContext(securityContext -> securityContext. + securityContextRepository(new HttpSessionSecurityContextRepository()) + ) + .saml2Login(withDefaults()) + .sessionManagement(sessionManagement -> sessionManagement.sessionFixation().migrateSession()) + // NOTE: I did not get the official .saml2Logout() DSL to work as + // described at https://docs.spring.io/spring-security/reference/6.1/servlet/saml2/logout.html + // Logout Service POST Binding URL: http://localhost:8080/logout/saml2/slo + .logout(logout -> logout + .logoutUrl(LOGOUT_URL) + .clearAuthentication(true) + .invalidateHttpSession(true) + .logoutSuccessHandler(logoutSuccessHandler) + ) + .logout(logout -> logout + .logoutUrl(BASIC_LOGOUT_URL) + .clearAuthentication(true) + .invalidateHttpSession(true) + ); + + http.apply(new BasicFilterDsl()); + return http.build(); + } + + private class BasicFilterDsl extends AbstractHttpConfigurer { + @Override + public void configure(HttpSecurity http) { + AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class); + UsernamePasswordAuthenticationFilter filter = + new UsernamePasswordAuthenticationFilter(); + filter.setPostOnly(false); + filter.setFilterProcessesUrl("/j_spring_security_check"); + filter.setUsernameParameter("j_username"); + filter.setPasswordParameter("j_password"); + filter.setAuthenticationManager(authenticationManager); + filter.setAuthenticationSuccessHandler(new BasicRestfulAuthenticationSuccessHandler()); + http.addFilterAfter(filter, SecurityContextHolderFilter.class); + } + } + + public void buildAuthenticationManager(AuthenticationManagerBuilder authenticationManagerBuilder, InMemoryUserDetailsManager userDetailsManager ) { + DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); + authenticationProvider.setUserDetailsService(userDetailsManager); + authenticationProvider.setPasswordEncoder(bCryptPasswordEncoder()); + authenticationManagerBuilder.authenticationProvider(authenticationProvider); + } + + + @Bean + public InMemoryUserDetailsManager userDetailsService() { + if(Objects.isNull(basicAuthorities)) { + basicAuthorities = "NOOP"; + } + + UserDetails user = User + .withUsername(this.basicUsername) + .password(this.basicPassword) + .roles(basicAuthorities.split(",")) + .build(); + return new InMemoryUserDetailsManager(user); + } + + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder() { + return new BCryptPasswordEncoder(10); + } + +} diff --git a/src/main/java/org/cbioportal/security/config/Saml2SecurityConfig.java b/src/main/java/org/cbioportal/security/config/Saml2SecurityConfig.java index a7fada979b7..527df01140b 100644 --- a/src/main/java/org/cbioportal/security/config/Saml2SecurityConfig.java +++ b/src/main/java/org/cbioportal/security/config/Saml2SecurityConfig.java @@ -1,12 +1,14 @@ package org.cbioportal.security.config; import org.cbioportal.security.util.GrantedAuthorityUtil; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.convert.converter.Converter; import org.springframework.http.HttpStatus; -import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; @@ -14,8 +16,13 @@ import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider; import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal; import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication; +import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; +import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver; +import org.springframework.security.saml2.provider.service.web.authentication.logout.OpenSaml4LogoutRequestResolver; +import org.springframework.security.saml2.provider.service.web.authentication.logout.Saml2RelyingPartyInitiatedLogoutSuccessHandler; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.HttpStatusEntryPoint; +import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import java.util.Collection; @@ -23,27 +30,49 @@ import java.util.Objects; import java.util.Set; +import static org.springframework.security.config.Customizer.withDefaults; + @Configuration @EnableWebSecurity +@ConditionalOnExpression("{'saml','saml_plus_basic'}.contains('${authenticate}')") public class Saml2SecurityConfig { + + private static final String LOGOUT_URL = "/logout"; + + @Value("${saml.idp.metadata.attribute.role:Role}") + private String roleAttributeName; + @Bean @ConditionalOnProperty(value = "authenticate", havingValue = "saml") - public SecurityFilterChain samlFilterChain(HttpSecurity http) throws Exception { - OpenSaml4AuthenticationProvider authenticationProvider = new OpenSaml4AuthenticationProvider(); - authenticationProvider.setResponseAuthenticationConverter(rolesConverter()); - - return http.authorizeHttpRequests(auth -> - auth.requestMatchers("/api/health", "/login", "/images/**" ).permitAll() + public SecurityFilterChain samlFilterChain(HttpSecurity http, RelyingPartyRegistrationRepository relyingPartyRegistrationRepository) throws Exception { + return http.csrf(AbstractHttpConfigurer::disable) + .cors(Customizer.withDefaults()) + .authorizeHttpRequests(auth -> + auth.requestMatchers("/api/health", "/images/**", "/js/**", "/login").permitAll() .anyRequest().authenticated()) - .exceptionHandling(eh -> - eh.defaultAuthenticationEntryPointFor(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED), AntPathRequestMatcher.antMatcher("/api/**"))) - .saml2Login(saml2 -> saml2 - .authenticationManager(new ProviderManager(authenticationProvider))) - .logout(logout -> logout.logoutSuccessUrl("/login?logout_success")) - .csrf(AbstractHttpConfigurer::disable) + .exceptionHandling(eh -> + eh.defaultAuthenticationEntryPointFor( + new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED), AntPathRequestMatcher.antMatcher("/api/**") + ) + ) + .saml2Login(withDefaults()) + // NOTE: I did not get the official .saml2Logout() DSL to work as + // described at https://docs.spring.io/spring-security/reference/6.1/servlet/saml2/logout.html + // Logout Service POST Binding URL: http://localhost:8080/logout/saml2/slo + .logout(logout -> logout + .logoutUrl(LOGOUT_URL) + .logoutSuccessHandler(logoutSuccessHandler(relyingPartyRegistrationRepository)) + ) .build(); } - + + @Bean + public OpenSaml4AuthenticationProvider openSaml4AuthenticationProvider() { + OpenSaml4AuthenticationProvider authenticationProvider = new OpenSaml4AuthenticationProvider(); + authenticationProvider.setResponseAuthenticationConverter(rolesConverter()); + return authenticationProvider; + } + private Converter rolesConverter() { Converter delegate = @@ -52,7 +81,7 @@ private Converter { Saml2Authentication authentication = delegate.convert(responseToken); var principal = (Saml2AuthenticatedPrincipal) Objects.requireNonNull(authentication).getPrincipal(); - Collection roles = principal.getAttribute("Role"); + Collection roles = principal.getAttribute(this.roleAttributeName); Set mappedAuthorities = new HashSet<>(); if (!Objects.isNull(roles)) { mappedAuthorities.addAll(GrantedAuthorityUtil.generateGrantedAuthoritiesFromRoles(roles)); @@ -62,4 +91,16 @@ private Converter. + */ + +package org.cbioportal.security.token; + +import java.io.IOException; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; + +public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint { + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, + AuthenticationException authException) throws IOException { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); + } + +} diff --git a/src/main/java/org/cbioportal/security/token/TokenAuthenticationFilter.java b/src/main/java/org/cbioportal/security/token/TokenAuthenticationFilter.java new file mode 100644 index 00000000000..42988160137 --- /dev/null +++ b/src/main/java/org/cbioportal/security/token/TokenAuthenticationFilter.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2018 Memorial Sloan-Kettering Cancer Center. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +package org.cbioportal.security.token; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.cbioportal.service.DataAccessTokenService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; + +import java.io.IOException; + +import static com.google.common.net.HttpHeaders.AUTHORIZATION; + +/** + * + * @author Manda Wilson + */ +public class TokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter { + + private DataAccessTokenService tokenService; + + private static final String BEARER = "Bearer"; + + private static final Logger LOG = LoggerFactory.getLogger(TokenAuthenticationFilter.class); + + public TokenAuthenticationFilter() { + // allow any request to contain an authorization header + super("/**"); + } + + public TokenAuthenticationFilter(String s, AuthenticationManager authenticationManagerBean) { + super(s, authenticationManagerBean); + } + + public TokenAuthenticationFilter(String s, AuthenticationManager authenticationManager, DataAccessTokenService tokenService) { + super(s, authenticationManager); + this.tokenService = tokenService; + } + + @Override + protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) { + // only required if we do see an authorization header + String param = request.getHeader(AUTHORIZATION); + if (param == null) { + LOG.debug("attemptAuthentication(), authorization header is null, continue on to other security filters"); + return false; + } + return true; + } + + @Override + public Authentication attemptAuthentication (HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, jakarta.servlet.ServletException{ + + String token = extractHeaderToken(request); + + if (token == null) { + LOG.error("No token was found in request header."); + throw new BadCredentialsException("No token was found in request header."); + } + + Authentication auth = tokenService.createAuthenticationRequest(token); + + return getAuthenticationManager().authenticate(auth); + } + + @Override + protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, jakarta.servlet.FilterChain chain, Authentication authResult) throws IOException, ServletException { + super.successfulAuthentication(request, response, chain, authResult); + chain.doFilter(request, response); + } + + /** + * Extract the bearer token from a header. + * + * @param request + * @return The token, or null if no authorization header was supplied + */ + protected String extractHeaderToken(HttpServletRequest request) { + String authorizationHeader = request.getHeader(AUTHORIZATION); + if (authorizationHeader != null && !authorizationHeader.isEmpty() && authorizationHeader.toLowerCase().startsWith(BEARER.toLowerCase())) { + return authorizationHeader.substring(BEARER.length()).trim(); + } + return null; + } + +} diff --git a/src/main/java/org/cbioportal/security/token/TokenAuthenticationSuccessHandler.java b/src/main/java/org/cbioportal/security/token/TokenAuthenticationSuccessHandler.java new file mode 100644 index 00000000000..b2db8dddabf --- /dev/null +++ b/src/main/java/org/cbioportal/security/token/TokenAuthenticationSuccessHandler.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018 Memorial Sloan-Kettering Cancer Center. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +package org.cbioportal.security.token; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.springframework.stereotype.Component; + +import java.io.IOException; + +@Component +public class TokenAuthenticationSuccessHandler implements AuthenticationSuccessHandler { + + @Override + public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { + // We do not need to do anything extra on REST authentication success, because there is no page to redirect to + } + +} diff --git a/src/main/java/org/cbioportal/security/token/config/DataAccessTokenConfig.java b/src/main/java/org/cbioportal/security/token/config/DataAccessTokenConfig.java new file mode 100644 index 00000000000..a800772cfa7 --- /dev/null +++ b/src/main/java/org/cbioportal/security/token/config/DataAccessTokenConfig.java @@ -0,0 +1,47 @@ +package org.cbioportal.security.token.config; + +import org.cbioportal.persistence.SecurityRepository; +import org.cbioportal.security.token.oauth2.JwtTokenVerifierBuilder; +import org.cbioportal.security.token.oauth2.OAuth2DataAccessTokenServiceImpl; +import org.cbioportal.security.token.oauth2.OAuth2TokenAuthenticationProvider; +import org.cbioportal.security.token.oauth2.OAuth2TokenRefreshRestTemplate; +import org.cbioportal.security.token.uuid.UuidTokenAuthenticationProvider; +import org.cbioportal.service.impl.UnauthDataAccessTokenServiceImpl; +import org.cbioportal.utils.config.annotation.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +@Configuration +@ConditionalOnProperty(name = "dat.method", havingValue = {"", "none"}, isNot = true) +public class DataAccessTokenConfig { + + + // provider + @Bean("tokenAuthenticationProvider") + @ConditionalOnProperty(name = "dat.method", havingValue = "oauth2") + public OAuth2TokenAuthenticationProvider oauth2TokenAuthenticationProvider(OAuth2TokenRefreshRestTemplate refreshRestTemplate) { + return new OAuth2TokenAuthenticationProvider(refreshRestTemplate); + } + + // TODO - implement jwt providers + @Bean("tokenAuthenticationProvider") + @ConditionalOnProperty(name = "dat.method", havingValue = "uuid") + public UuidTokenAuthenticationProvider uuidTokenAuthenticationProvider(SecurityRepository repository) { + return new UuidTokenAuthenticationProvider(repository); + } + + // service + @Bean("dataAccessTokenService") + @ConditionalOnProperty(name = "dat.method", havingValue = "oauth2") + public OAuth2DataAccessTokenServiceImpl oauth2DataAccessTokenService(RestTemplate template, JwtTokenVerifierBuilder jwtTokenVerifierBuilder) { + return new OAuth2DataAccessTokenServiceImpl(template, jwtTokenVerifierBuilder); + } + + @Bean("dataAccessTokenService") + @ConditionalOnProperty(name = "dat.method", havingValue = "none") + public UnauthDataAccessTokenServiceImpl unauthDataAccessTokenService() { + return new UnauthDataAccessTokenServiceImpl(); + } + +} \ No newline at end of file diff --git a/src/main/java/org/cbioportal/security/token/oauth2/JwtTokenVerifierBuilder.java b/src/main/java/org/cbioportal/security/token/oauth2/JwtTokenVerifierBuilder.java new file mode 100644 index 00000000000..a14fba88b1e --- /dev/null +++ b/src/main/java/org/cbioportal/security/token/oauth2/JwtTokenVerifierBuilder.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020 The Hyve B.V. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ +package org.cbioportal.security.token.oauth2; + +import java.net.MalformedURLException; +import java.net.URL; +import java.security.interfaces.RSAPublicKey; + +import com.auth0.jwk.Jwk; +import com.auth0.jwk.JwkException; +import com.auth0.jwk.JwkProvider; +import com.auth0.jwk.UrlJwkProvider; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.jwt.crypto.sign.RsaVerifier; +import org.springframework.stereotype.Component; + +@Component +public class JwtTokenVerifierBuilder { + + @Value("${dat.oauth2.jwkUrl:}") + private String jwkUrl; + + public RsaVerifier build(final String kid) throws MalformedURLException, JwkException { + final JwkProvider provider = new UrlJwkProvider(new URL(jwkUrl)); + final Jwk jwk = provider.get(kid); + final RSAPublicKey publicKey = (RSAPublicKey) jwk.getPublicKey(); + return new RsaVerifier(publicKey, "SHA512withRSA"); + } + +} \ No newline at end of file diff --git a/src/main/java/org/cbioportal/security/token/oauth2/OAuth2BearerAuthenticationToken.java b/src/main/java/org/cbioportal/security/token/oauth2/OAuth2BearerAuthenticationToken.java new file mode 100644 index 00000000000..1e60681df90 --- /dev/null +++ b/src/main/java/org/cbioportal/security/token/oauth2/OAuth2BearerAuthenticationToken.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2020 The Hyve B.V. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +package org.cbioportal.security.token.oauth2; + +import java.util.Collection; +import java.util.HashSet; + +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; + +/** + * OAuth2BearerAuthenticationToken + */ +public class OAuth2BearerAuthenticationToken extends AbstractAuthenticationToken { + + private static final long serialVersionUID = 1L; + private final String accessToken; + private final Object principal; + + public OAuth2BearerAuthenticationToken(String accessToken) { + super(new HashSet<>()); + this.principal = null; + this.accessToken = accessToken; + } + + public OAuth2BearerAuthenticationToken(Object principal, String accessToken) { + super(new HashSet<>()); + this.accessToken = accessToken; + this.principal = principal; + } + + public OAuth2BearerAuthenticationToken(Object principal, Collection authorities) { + super(authorities); + accessToken = null; + this.principal = principal; + setAuthenticated(true); + } + + @Override + public Object getCredentials() { + return accessToken; + } + + @Override + public Object getPrincipal() { + return principal; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/cbioportal/security/OAuth2DataAccessTokenServiceImpl.java b/src/main/java/org/cbioportal/security/token/oauth2/OAuth2DataAccessTokenServiceImpl.java similarity index 77% rename from src/main/java/org/cbioportal/security/OAuth2DataAccessTokenServiceImpl.java rename to src/main/java/org/cbioportal/security/token/oauth2/OAuth2DataAccessTokenServiceImpl.java index 796028fe89f..9e546ce10bf 100644 --- a/src/main/java/org/cbioportal/security/OAuth2DataAccessTokenServiceImpl.java +++ b/src/main/java/org/cbioportal/security/token/oauth2/OAuth2DataAccessTokenServiceImpl.java @@ -30,7 +30,7 @@ * along with this program. If not, see . */ -package org.cbioportal.security; +package org.cbioportal.security.token.oauth2; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -38,22 +38,21 @@ import org.cbioportal.service.DataAccessTokenService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; -import org.springframework.stereotype.Component; +import org.springframework.security.jwt.Jwt; +import org.springframework.security.jwt.JwtHelper; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; +import java.io.IOException; import java.util.Date; import java.util.List; -@Component -@ConditionalOnProperty(value = "dat.method", havingValue = "oauth2") public class OAuth2DataAccessTokenServiceImpl implements DataAccessTokenService { @Value("${dat.oauth2.issuer}") private String issuer; @@ -67,19 +66,25 @@ public class OAuth2DataAccessTokenServiceImpl implements DataAccessTokenService @Value("${dat.oauth2.accessTokenUri}") private String accessTokenUri; - @Value("${dat.oauth2.userAuthorizationUri}") - private String userAuthorizationUri; - @Value("${dat.oauth2.redirectUri}") private String redirectUri; + private final RestTemplate template; + + private final JwtTokenVerifierBuilder jwtTokenVerifierBuilder; + + @Autowired + public OAuth2DataAccessTokenServiceImpl(RestTemplate template, JwtTokenVerifierBuilder jwtTokenVerifierBuilder) { + this.template = template; + this.jwtTokenVerifierBuilder = jwtTokenVerifierBuilder; + } + @Override // request offline token from authentication server via back channel public DataAccessToken createDataAccessToken(final String accessCode) { HttpHeaders headers = new HttpHeaders(); - RestTemplate template = new RestTemplate(); - + MultiValueMap map = new LinkedMultiValueMap<>(); map.add("grant_type", "authorization_code"); map.add("code", accessCode); @@ -95,7 +100,7 @@ public DataAccessToken createDataAccessToken(final String accessCode) { String offlineToken = ""; try { JsonNode json = new ObjectMapper().readTree(response.getBody()); - offlineToken = json.get("access_token").asText(); + offlineToken = json.get("refresh_token").asText(); } catch (Exception e) { throw new BadCredentialsException("Offline token could not be retrieved using access_code: "+ accessCode ); } @@ -135,12 +140,40 @@ public void revokeDataAccessToken(final String token) { @Override public Boolean isValid(final String token) { - return false; + final String kid = JwtHelper.headers(token).get("kid"); + try { + + final Jwt tokenDecoded = JwtHelper.decodeAndVerify(token, jwtTokenVerifierBuilder.build(kid)); + final String claims = tokenDecoded.getClaims(); + final JsonNode claimsMap = new ObjectMapper().readTree(claims); + + hasValidIssuer(claimsMap); + hasValidClientId(claimsMap); + + } catch (Exception e) { + throw new BadCredentialsException("Token is not valid (wrong key, issuer, or audience)."); + } + return true; } @Override public String getUsername(final String token) { - return "noop"; + + final Jwt tokenDecoded = JwtHelper.decode(token); + + final String claims = tokenDecoded.getClaims(); + JsonNode claimsMap; + try { + claimsMap = new ObjectMapper().readTree(claims); + } catch (IOException e) { + throw new BadCredentialsException("User name could not be found in offline token."); + } + + if (! claimsMap.has("sub")) { + throw new BadCredentialsException("User name could not be found in offline token."); + } + + return claimsMap.get("sub").asText(); } @Override @@ -163,7 +196,7 @@ private void hasValidClientId(final JsonNode claimsMap) throws BadCredentialsExc @Override public Authentication createAuthenticationRequest(String offlineToken) { // validity of the offline token is checked by the OAuth2 authentication server - throw new UnsupportedOperationException("this implementation of (pure) Data Access Tokens does not allow retrieval of stored tokens"); + return new OAuth2BearerAuthenticationToken(offlineToken); } } diff --git a/src/main/java/org/cbioportal/security/token/oauth2/OAuth2TokenAuthenticationProvider.java b/src/main/java/org/cbioportal/security/token/oauth2/OAuth2TokenAuthenticationProvider.java new file mode 100644 index 00000000000..d8dfafa7b66 --- /dev/null +++ b/src/main/java/org/cbioportal/security/token/oauth2/OAuth2TokenAuthenticationProvider.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2020 The Hyve B.V. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +package org.cbioportal.security.token.oauth2; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.cbioportal.security.util.ClaimRoleExtractorUtil; +import org.cbioportal.security.util.GrantedAuthorityUtil; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.jwt.Jwt; +import org.springframework.security.jwt.JwtHelper; + +import java.io.IOException; +import java.util.Collection; + +public class OAuth2TokenAuthenticationProvider implements AuthenticationProvider { + + @Value("${dat.oauth2.jwtRolesPath:resource_access::cbioportal::roles}") + private String jwtRolesPath; + + private final OAuth2TokenRefreshRestTemplate tokenRefreshRestTemplate; + + public OAuth2TokenAuthenticationProvider(OAuth2TokenRefreshRestTemplate tokenRefreshRestTemplate) { + this.tokenRefreshRestTemplate = tokenRefreshRestTemplate; + } + @Override + public boolean supports(Class authentication) { + return authentication.isAssignableFrom(OAuth2BearerAuthenticationToken.class); + } + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + + String offlineToken = (String) authentication.getCredentials(); + + // Note: validity of the offline token is not checked in cBioPortal + // backend, is handeled by the OAuth2 authentication server. + + // request an access token from the OAuth2 identity provider + final String accessToken = tokenRefreshRestTemplate.getAccessToken(offlineToken); + + Collection authorities = extractAuthorities(accessToken); + String username = getUsername(accessToken); + + return new OAuth2BearerAuthenticationToken(username, authorities); + } + + // Read roles/authorities from JWT token. + private Collection extractAuthorities(final String token) throws BadCredentialsException { + try { + final Jwt tokenDecoded = JwtHelper.decode(token); + final String claims = tokenDecoded.getClaims(); + return GrantedAuthorityUtil.generateGrantedAuthoritiesFromRoles(ClaimRoleExtractorUtil.extractClientRoles(claims, jwtRolesPath)); + + } catch (Exception e) { + throw new BadCredentialsException("Authorities could not be extracted from access token."); + } + } + + private String getUsername(final String token) { + + final Jwt tokenDecoded = JwtHelper.decode(token); + + final String claims = tokenDecoded.getClaims(); + JsonNode claimsMap; + try { + claimsMap = new ObjectMapper().readTree(claims); + } catch (IOException e) { + throw new BadCredentialsException("User name could not be found in access token."); + } + + if (! claimsMap.has("sub")) { + throw new BadCredentialsException("User name could not be found in access token."); + } + + return claimsMap.get("sub").asText(); + } + +} diff --git a/src/main/java/org/cbioportal/security/token/oauth2/OAuth2TokenDataAccessConfiguration.java b/src/main/java/org/cbioportal/security/token/oauth2/OAuth2TokenDataAccessConfiguration.java new file mode 100644 index 00000000000..f9dc65c0889 --- /dev/null +++ b/src/main/java/org/cbioportal/security/token/oauth2/OAuth2TokenDataAccessConfiguration.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020 The Hyve B.V. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +package org.cbioportal.security.token.oauth2; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class OAuth2TokenDataAccessConfiguration { + + @Bean + // This bean is defined here so + // that it can be stubbed in tests. + public RestTemplate restTemplate() { + return new RestTemplate(); + } + +} \ No newline at end of file diff --git a/src/main/java/org/cbioportal/security/token/oauth2/OAuth2TokenRefreshRestTemplate.java b/src/main/java/org/cbioportal/security/token/oauth2/OAuth2TokenRefreshRestTemplate.java new file mode 100644 index 00000000000..fefe7ccb2d8 --- /dev/null +++ b/src/main/java/org/cbioportal/security/token/oauth2/OAuth2TokenRefreshRestTemplate.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2020 The Hyve B.V. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +package org.cbioportal.security.token.oauth2; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +@Component +public class OAuth2TokenRefreshRestTemplate { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + @Value("${dat.oauth2.clientId:}") + private String clientId; + + @Value("${dat.oauth2.clientSecret:}") + private String clientSecret; + + @Value("${dat.oauth2.accessTokenUri:}") + private String accessTokenUri; + + private final RestTemplate template; + + @Autowired + public OAuth2TokenRefreshRestTemplate(RestTemplate template) { + this.template = template; + } + + public String getAccessToken(String offlineToken) throws BadCredentialsException { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("grant_type", "refresh_token"); + map.add("client_id", clientId); + map.add("client_secret", clientSecret); + map.add("refresh_token", offlineToken); + + HttpEntity> request = new HttpEntity<>(map, headers); + + ResponseEntity response = null; + try { + response = template.postForEntity(accessTokenUri, request, String.class); + String accessToken = new ObjectMapper().readTree(response.getBody()).get("access_token").asText(); + logger.debug("Received access token from authentication server:\n{}",accessToken); + return accessToken; + } catch (Exception e) { + logger.error("Authentication server did not return an access token. Server response:\n{}",response); + throw new BadCredentialsException("Authentication server did not return an access token."); + } + + } + +} diff --git a/src/main/java/org/cbioportal/security/token/uuid/UuidTokenAuthenticationProvider.java b/src/main/java/org/cbioportal/security/token/uuid/UuidTokenAuthenticationProvider.java new file mode 100644 index 00000000000..85268a3df22 --- /dev/null +++ b/src/main/java/org/cbioportal/security/token/uuid/UuidTokenAuthenticationProvider.java @@ -0,0 +1,43 @@ +package org.cbioportal.security.token.uuid; + +import org.cbioportal.model.UserAuthorities; +import org.cbioportal.persistence.SecurityRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.AuthorityUtils; + +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +public class UuidTokenAuthenticationProvider implements AuthenticationProvider { + private static final Logger log = LoggerFactory.getLogger(UuidTokenAuthenticationProvider.class); + + private final SecurityRepository securityRepository; + + public UuidTokenAuthenticationProvider(final SecurityRepository securityRepository) { + this.securityRepository = securityRepository; + } + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + String user = (String) authentication.getPrincipal(); + log.debug("Attempt to grab user Authorities for user: {}", user); + UserAuthorities authorities = securityRepository.getPortalUserAuthorities(user); + Set mappedAuthorities = new HashSet<>(); + if (!Objects.isNull(authorities)) { + mappedAuthorities.addAll(AuthorityUtils.createAuthorityList(authorities.getAuthorities())); + } + return new UsernamePasswordAuthenticationToken(user, "does not match unused", mappedAuthorities); + } + + @Override + public boolean supports(Class authentication) { + return authentication.isAssignableFrom(UsernamePasswordAuthenticationToken.class); + } +} diff --git a/src/main/java/org/cbioportal/security/util/ClaimRoleExtractorUtil.java b/src/main/java/org/cbioportal/security/util/ClaimRoleExtractorUtil.java index d6ea2a59c21..1f3e094529a 100644 --- a/src/main/java/org/cbioportal/security/util/ClaimRoleExtractorUtil.java +++ b/src/main/java/org/cbioportal/security/util/ClaimRoleExtractorUtil.java @@ -1,28 +1,64 @@ package org.cbioportal.security.util; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.security.authentication.BadCredentialsException; import java.util.Collection; import java.util.Collections; import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; public class ClaimRoleExtractorUtil { private static final Logger log = LoggerFactory.getLogger(ClaimRoleExtractorUtil.class); - private static final String CLAIM_RESOURCE_ACCESS = "resource_access"; - private static final String CLAIM_ROLES = "roles"; - public static Collection extractClientRoles(final String clientId, final Map claims) { + public static Collection extractClientRoles(final Map claims, final String jwtRolesPath) { try { - if(claims.containsKey(CLAIM_RESOURCE_ACCESS)) { - var realmAccess = (Map) claims.get(CLAIM_RESOURCE_ACCESS); - var clientIdAccess = (Map) realmAccess.get(clientId); - return (clientIdAccess.containsKey(CLAIM_ROLES)) ? (Collection) clientIdAccess.get(CLAIM_ROLES) : Collections.emptyList(); - } + // Convert the map to a JSON string + ObjectMapper objectMapper = new ObjectMapper(); + String jsonString = objectMapper.writeValueAsString(claims); + + JsonNode rolesCursor = new ObjectMapper().readTree(jsonString); + return extractClientRoles(rolesCursor, jwtRolesPath); } catch (Exception e) { - log.error("Error Grabbing Client Roles from OIDC User Info: Realm roles must follow the convention resource_access:client_id:roles"); + log.error("Error extracting claims as a json string"); } return Collections.emptyList(); } + + public static Collection extractClientRoles(final String claims, final String jwtRolesPath) { + try { + JsonNode rolesCursor = new ObjectMapper().readTree(claims); + return extractClientRoles(rolesCursor, jwtRolesPath); + } catch (Exception e) { + log.error("Error converting Json String to JsonNode Object"); + } + return Collections.emptyList(); + } + + public static Collection extractClientRoles(final JsonNode claims, final String jwtRolesPath) { + try { + + JsonNode rolesCursor = claims; + for (var keyName : jwtRolesPath.split("::")) { + if (rolesCursor.has(keyName)) { + rolesCursor = rolesCursor.get(keyName); + } else { + throw new BadCredentialsException("Cannot Find user Roles in JWT Access Token "); + } + + } + return StreamSupport.stream(rolesCursor.spliterator(), false) + .map(JsonNode::asText) + .collect(Collectors.toSet()); + } catch (Exception e) { + log.error("Error Grabbing Client Roles from OIDC User Info: Realm roles must follow the convention {}", jwtRolesPath); + } + return Collections.emptyList(); + } + } diff --git a/src/main/java/org/cbioportal/security/util/GrantedAuthorityUtil.java b/src/main/java/org/cbioportal/security/util/GrantedAuthorityUtil.java index 372cd12f13b..68645faf456 100644 --- a/src/main/java/org/cbioportal/security/util/GrantedAuthorityUtil.java +++ b/src/main/java/org/cbioportal/security/util/GrantedAuthorityUtil.java @@ -9,6 +9,6 @@ public class GrantedAuthorityUtil { private static final String PREFIX_RESOURCE_ROLE = "ROLE_"; public static Collection generateGrantedAuthoritiesFromRoles(Collection roles) { - return roles.stream().map(role -> new SimpleGrantedAuthority(PREFIX_RESOURCE_ROLE + role)).collect(Collectors.toList()); + return roles.stream().map(role -> new SimpleGrantedAuthority(PREFIX_RESOURCE_ROLE + role)).collect(Collectors.toSet()); } } diff --git a/src/main/java/org/cbioportal/service/FrontendPropertiesServiceImpl.java b/src/main/java/org/cbioportal/service/FrontendPropertiesServiceImpl.java index 151f016d355..da96d0debfa 100644 --- a/src/main/java/org/cbioportal/service/FrontendPropertiesServiceImpl.java +++ b/src/main/java/org/cbioportal/service/FrontendPropertiesServiceImpl.java @@ -1,5 +1,12 @@ package org.cbioportal.service; +import jakarta.annotation.PostConstruct; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Service; + import java.io.BufferedReader; import java.io.IOException; import java.nio.file.Files; @@ -9,16 +16,6 @@ import java.util.Map; import java.util.stream.Collectors; -import jakarta.annotation.PostConstruct; -import org.cbioportal.service.util.MskWholeSlideViewerTokenGenerator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.env.Environment; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.stereotype.Service; - // Class adapted from legacy config_service.jsp and GlobalProperties.java @Service @@ -33,6 +30,8 @@ public enum FrontendProperty { dat_method("dat.method", null), oncoprint_custom_driver_annotation_binary_menu_label( "oncoprint.custom_driver_annotation.binary.menu_label", null), + oncoprint_custom_driver_annotation_binary_menu_description( + "oncoprint.custom_driver_annotation.binary.menu_description", null), disabled_tabs("disabled_tabs", null), civic_url("civic.url", null), oncoprint_custom_driver_annotation_binary_default( @@ -59,6 +58,8 @@ public enum FrontendProperty { show_mdacc_heatmap("show.mdacc.heatmap", null), oncoprint_custom_driver_annotation_tiers_menu_label( "oncoprint.custom_driver_annotation.tiers.menu_label", null), + oncoprint_custom_driver_annotation_tiers_menu_description( + "oncoprint.custom_driver_annotation.tiers.menu_description", null), patient_view_use_legacy_timeline("patient_view.use_legacy_timeline", null), installation_map_url("installation_map_url", null), priority_studies("priority_studies", null), @@ -125,6 +126,7 @@ public enum FrontendProperty { default_cross_cancer_study_list_name("default_cross_cancer_study_list_name", null), skin_description("skin.description", null), skin_title("skin.title", null), + app_name("app.name", null), skin_authorization_message("skin.authorization_message", null), session_url_length_threshold("session.url_length_threshold", null), bitly_api_key("bitly.api_key", null), @@ -172,11 +174,18 @@ public enum FrontendProperty { skin_results_view_mutation_table_columns_show_on_init("skin.results_view.mutation_table.columns.show_on_init", null), skin_patient_view_copy_number_table_columns_show_on_init("skin.patient_view.copy_number_table.columns.show_on_init", null), skin_patient_view_structural_variant_table_columns_show_on_init("skin.patient_view.structural_variant_table.columns.show_on_init", null), + skin_results_view_tables_default_sort_column("skin.results_view.tables.default_sort_column", null), + + skin_patient_view_tables_default_sort_column("skin.patient_view.tables.default_sort_column", null), enable_treatment_groups("enable_treatment_groups", null), comparison_categorical_na_values("comparison.categorical_na_values", null), clinical_attribute_product_limit("clinical_attribute_product_limit", null), - skin_right_nav_show_web_tours("skin.right_nav.show_web_tours", "false"); + skin_right_nav_show_web_tours("skin.right_nav.show_web_tours", "false"), + + enable_study_tags("enable_study_tags", null), + enable_darwin("enable_darwin", null); + private final String propertyName; private final String defaultValue; @@ -225,8 +234,6 @@ private String getPropertyValue(FrontendProperty property) { case "skin.patient_view.custom_sample_type_colors_json": case "oncoprint.clinical_tracks.config_json": return readFile(propertyValue); - case "mskWholeSlideViewerToken": - return getMskWholeSlideViewerToken(propertyValue); case "oncoprintOncoKbHotspotsDefault": return enableOncoKBandHotspotsParamValue(propertyValue); case "oncoKbTokenDefined": @@ -234,29 +241,14 @@ private String getPropertyValue(FrontendProperty property) { return String.valueOf(!propertyValue.isEmpty()); case "frontendUrl": return getFrontendUrl(propertyValue); + case "enable_darwin": + return enableDarwin(); // For others, just return the value in the properties file. default: return propertyValue; } } - private String getMskWholeSlideViewerToken(String secretKey) { - // this token is for the msk portal - // the token is generated based on users' timestamp to let the slide viewer know whether the token is expired and then decide whether to allow the user to login the viewer - // every time when we refresh the page or goto the new page, a new token should be generated - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - String timeStamp = String.valueOf(System.currentTimeMillis()); - - if (authentication != null && authentication.isAuthenticated() && secretKey != null && - !secretKey.isEmpty()) { - return "{ \"token\":\"" + MskWholeSlideViewerTokenGenerator.generateTokenByHmacSHA256( - authentication.getName(), secretKey, timeStamp) + "\", \"time\":\"" + timeStamp + - "\"}"; - } else { - return null; - } - } - private String enableOncoKBandHotspots(String enableOncoKBandHotspots) { if (enableOncoKBandHotspots.equalsIgnoreCase("custom")) { return "custom"; @@ -327,6 +319,18 @@ public String getFrontendUrl(String propertyValue) { return propertyValue; } + public String enableDarwin() { + String darwinAuthUrl = env.getProperty("darwin.auth_url", ""); + String ddpResponseUrl = env.getProperty("ddp.response_url", ""); + String cisUser = env.getProperty("cis.user", ""); + String darwinRegex = env.getProperty("darwin.regex", ""); + if (!darwinAuthUrl.isBlank() && !ddpResponseUrl.isBlank() && !cisUser.isBlank() && !darwinRegex.isBlank()) { + return "true"; + } else { + return "false"; + } + } + /* * Trim whitespace of url and append / if it does not exist. Return empty * string otherwise. diff --git a/src/main/java/org/cbioportal/service/MolecularProfileService.java b/src/main/java/org/cbioportal/service/MolecularProfileService.java index d3de570f6e8..e3724261798 100644 --- a/src/main/java/org/cbioportal/service/MolecularProfileService.java +++ b/src/main/java/org/cbioportal/service/MolecularProfileService.java @@ -40,6 +40,7 @@ List getMolecularProfilesReferringTo(String referredMolecularP List getMolecularProfileCaseIdentifiers(List studyIds, List sampleIds); List getFirstMutationProfileCaseIdentifiers(List studyIds, List sampleIds); + List getMutationProfileCaseIdentifiers(List studyIds, List sampleIds); List getFirstDiscreteCNAProfileCaseIdentifiers(List studyIds, List sampleIds); List getFirstStructuralVariantProfileCaseIdentifiers(List studyIds, List sampleIds); } diff --git a/src/main/java/org/cbioportal/service/MutationService.java b/src/main/java/org/cbioportal/service/MutationService.java index 4f5b1f5d65f..c51153d1111 100644 --- a/src/main/java/org/cbioportal/service/MutationService.java +++ b/src/main/java/org/cbioportal/service/MutationService.java @@ -1,6 +1,9 @@ package org.cbioportal.service; -import org.cbioportal.model.*; +import org.cbioportal.model.GeneFilterQuery; +import org.cbioportal.model.GenomicDataCountItem; +import org.cbioportal.model.Mutation; +import org.cbioportal.model.MutationCountByPosition; import org.cbioportal.model.meta.MutationMeta; import org.cbioportal.service.exception.MolecularProfileNotFoundException; @@ -9,7 +12,7 @@ public interface MutationService { List getMutationsInMolecularProfileBySampleListId(String molecularProfileId, String sampleListId, - List entrezGeneIds, Boolean snpOnly, + List entrezGeneIds, boolean snpOnly, String projection, Integer pageSize, Integer pageNumber, String sortBy, String direction) throws MolecularProfileNotFoundException; @@ -32,7 +35,7 @@ MutationMeta getMetaMutationsInMultipleMolecularProfiles(List molecularP List entrezGeneIds); List fetchMutationsInMolecularProfile(String molecularProfileId, List sampleIds, - List entrezGeneIds, Boolean snpOnly, String projection, + List entrezGeneIds, boolean snpOnly, String projection, Integer pageSize, Integer pageNumber, String sortBy, String direction) throws MolecularProfileNotFoundException; @@ -44,4 +47,7 @@ MutationMeta fetchMetaMutationsInMolecularProfile(String molecularProfileId, Lis List fetchMutationCountsByPosition(List entrezGeneIds, List proteinPosStarts, List proteinPosEnds); + + GenomicDataCountItem getMutationCountsByType(List molecularProfileIds, List sampleIds, + List entrezGeneIds, String profileType); } diff --git a/src/main/java/org/cbioportal/service/StudyViewService.java b/src/main/java/org/cbioportal/service/StudyViewService.java index 67191ea7588..c4cb00151e5 100644 --- a/src/main/java/org/cbioportal/service/StudyViewService.java +++ b/src/main/java/org/cbioportal/service/StudyViewService.java @@ -1,8 +1,13 @@ package org.cbioportal.service; import org.apache.commons.math3.util.Pair; -import org.cbioportal.model.*; -import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import org.cbioportal.model.AlterationCountByGene; +import org.cbioportal.model.AlterationCountByStructuralVariant; +import org.cbioportal.model.AlterationFilter; +import org.cbioportal.model.CopyNumberCountByGene; +import org.cbioportal.model.GenericAssayDataCountItem; +import org.cbioportal.model.GenomicDataCount; +import org.cbioportal.model.GenomicDataCountItem; import org.cbioportal.service.exception.StudyNotFoundException; import java.util.List; @@ -13,6 +18,10 @@ public interface StudyViewService { List getMutationAlterationCountByGenes(List studyIds, List sampleIds, AlterationFilter annotationFilter) throws StudyNotFoundException; + List getMutationCountsByGeneSpecific(List studyIds, List sampleIds, List> genomicDataFilters, AlterationFilter annotationFilter); + + List getMutationTypeCountsByGeneSpecific(List studyIds, List sampleIds, List> genomicDataFilters); + List getStructuralVariantAlterationCountByGenes(List studyIds, List sampleIds, AlterationFilter annotationFilter) throws StudyNotFoundException; diff --git a/src/main/java/org/cbioportal/service/impl/CacheServiceImpl.java b/src/main/java/org/cbioportal/service/impl/CacheServiceImpl.java index 6e0de479f55..41896b98d9b 100644 --- a/src/main/java/org/cbioportal/service/impl/CacheServiceImpl.java +++ b/src/main/java/org/cbioportal/service/impl/CacheServiceImpl.java @@ -1,6 +1,5 @@ package org.cbioportal.service.impl; -import java.util.stream.Collectors; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.cbioportal.persistence.StudyRepository; @@ -10,12 +9,12 @@ import org.cbioportal.service.CacheService; import org.cbioportal.service.exception.CacheOperationException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.cache.CacheManager; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; @Component public class CacheServiceImpl implements CacheService { @@ -25,7 +24,6 @@ public class CacheServiceImpl implements CacheService { @Autowired(required = false) private CacheManager cacheManager; - @Qualifier("staticRefCacheMapUtil") @Autowired private CacheMapUtil cacheMapUtil; diff --git a/src/main/java/org/cbioportal/service/impl/MolecularProfileServiceImpl.java b/src/main/java/org/cbioportal/service/impl/MolecularProfileServiceImpl.java index dd420d3af8b..3a4d6c8a1d7 100644 --- a/src/main/java/org/cbioportal/service/impl/MolecularProfileServiceImpl.java +++ b/src/main/java/org/cbioportal/service/impl/MolecularProfileServiceImpl.java @@ -9,14 +9,17 @@ import org.cbioportal.service.exception.MolecularProfileNotFoundException; import org.cbioportal.service.exception.StudyNotFoundException; import org.cbioportal.service.util.MolecularProfileUtil; +import org.cbioportal.web.parameter.Projection; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.access.prepost.PostFilter; import org.springframework.stereotype.Service; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.Set; import java.util.function.Predicate; -import java.util.stream.Collectors; @Service public class MolecularProfileServiceImpl implements MolecularProfileService { @@ -125,9 +128,14 @@ public List getMolecularProfileCaseIdentifiers(L @Override public List getFirstMutationProfileCaseIdentifiers(List studyIds, List sampleIds) { - return getFilteredMolecularProfileCaseIdentifiers(studyIds, sampleIds, Optional.of(molecularProfileUtil.isMutationProfile)); + return getFirstFilteredMolecularProfileCaseIdentifiers(studyIds, sampleIds, Optional.of(molecularProfileUtil.isMutationProfile)); } + @Override + public List getMutationProfileCaseIdentifiers(List studyIds, List sampleIds) { + return getFilteredMolecularProfileCaseIdentifiers(studyIds, sampleIds, Optional.of(molecularProfileUtil.isMutationProfile)); + } + @Override public List getFirstDiscreteCNAProfileCaseIdentifiers(List studyIds, List sampleIds) { return getFilteredMolecularProfileCaseIdentifiers(studyIds, sampleIds, Optional.of(molecularProfileUtil.isDiscreteCNAMolecularProfile)); @@ -135,12 +143,18 @@ public List getFirstDiscreteCNAProfileCaseIdenti @Override public List getFirstStructuralVariantProfileCaseIdentifiers(List studyIds, List sampleIds) { - return getFilteredMolecularProfileCaseIdentifiers(studyIds, sampleIds, Optional.of(molecularProfileUtil.isStructuralVariantMolecularProfile)); + return getFirstFilteredMolecularProfileCaseIdentifiers(studyIds, sampleIds, Optional.of(molecularProfileUtil.isStructuralVariantMolecularProfile)); + } + + private List getFirstFilteredMolecularProfileCaseIdentifiers(List studyIds, List sampleIds, Optional> profileFilter) { + List molecularProfiles = + getMolecularProfilesInStudies(studyIds.stream().distinct().toList(), Projection.SUMMARY.name()); + return molecularProfileUtil.getFirstFilteredMolecularProfileCaseIdentifiers(molecularProfiles, studyIds, sampleIds, profileFilter); } private List getFilteredMolecularProfileCaseIdentifiers(List studyIds, List sampleIds, Optional> profileFilter) { List molecularProfiles = - getMolecularProfilesInStudies(studyIds.stream().distinct().collect(Collectors.toList()), "SUMMARY"); + getMolecularProfilesInStudies(studyIds.stream().distinct().toList(), Projection.SUMMARY.name()); return molecularProfileUtil.getFilteredMolecularProfileCaseIdentifiers(molecularProfiles, studyIds, sampleIds, profileFilter); } } diff --git a/src/main/java/org/cbioportal/service/impl/MutationServiceImpl.java b/src/main/java/org/cbioportal/service/impl/MutationServiceImpl.java index 9480ac0f043..44602217b68 100644 --- a/src/main/java/org/cbioportal/service/impl/MutationServiceImpl.java +++ b/src/main/java/org/cbioportal/service/impl/MutationServiceImpl.java @@ -1,6 +1,7 @@ package org.cbioportal.service.impl; import org.cbioportal.model.GeneFilterQuery; +import org.cbioportal.model.GenomicDataCountItem; import org.cbioportal.model.MolecularProfile; import org.cbioportal.model.Mutation; import org.cbioportal.model.MutationCountByPosition; @@ -25,7 +26,7 @@ public class MutationServiceImpl implements MutationService { @Override public List getMutationsInMolecularProfileBySampleListId(String molecularProfileId, String sampleListId, - List entrezGeneIds, Boolean snpOnly, + List entrezGeneIds, boolean snpOnly, String projection, Integer pageSize, Integer pageNumber, String sortBy, String direction) @@ -84,7 +85,7 @@ public MutationMeta getMetaMutationsInMultipleMolecularProfiles(List mol @Override public List fetchMutationsInMolecularProfile(String molecularProfileId, List sampleIds, - List entrezGeneIds, Boolean snpOnly, + List entrezGeneIds, boolean snpOnly, String projection, Integer pageSize, Integer pageNumber, String sortBy, String direction) throws MolecularProfileNotFoundException { @@ -123,6 +124,12 @@ public List fetchMutationCountsByPosition(List return mutationCountByPositionList; } + @Override + public GenomicDataCountItem getMutationCountsByType(List molecularProfileIds, List sampleIds, + List entrezGeneIds, String profileType) { + return mutationRepository.getMutationCountsByType(molecularProfileIds, sampleIds, entrezGeneIds, profileType); + } + private MolecularProfile validateMolecularProfile(String molecularProfileId) throws MolecularProfileNotFoundException { MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); diff --git a/src/main/java/org/cbioportal/service/impl/StudyViewServiceImpl.java b/src/main/java/org/cbioportal/service/impl/StudyViewServiceImpl.java index 510fa8f0206..e84f146e459 100644 --- a/src/main/java/org/cbioportal/service/impl/StudyViewServiceImpl.java +++ b/src/main/java/org/cbioportal/service/impl/StudyViewServiceImpl.java @@ -3,17 +3,51 @@ import org.apache.commons.collections4.map.MultiKeyMap; import org.apache.commons.lang3.StringUtils; import org.apache.commons.math3.util.Pair; -import org.cbioportal.model.*; +import org.cbioportal.model.AlterationCountByGene; +import org.cbioportal.model.AlterationCountByStructuralVariant; +import org.cbioportal.model.AlterationFilter; +import org.cbioportal.model.CNA; +import org.cbioportal.model.CopyNumberCountByGene; +import org.cbioportal.model.Gene; +import org.cbioportal.model.GeneMolecularData; +import org.cbioportal.model.GenePanelData; +import org.cbioportal.model.GenericAssayData; +import org.cbioportal.model.GenericAssayDataCount; +import org.cbioportal.model.GenericAssayDataCountItem; +import org.cbioportal.model.GenomicDataCount; +import org.cbioportal.model.GenomicDataCountItem; +import org.cbioportal.model.Gistic; +import org.cbioportal.model.MolecularProfile; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.model.MutSig; +import org.cbioportal.model.MutationFilterOption; import org.cbioportal.model.util.Select; -import org.cbioportal.persistence.AlterationRepository; -import org.cbioportal.service.*; +import org.cbioportal.service.AlterationCountService; +import org.cbioportal.service.GenePanelService; +import org.cbioportal.service.GeneService; +import org.cbioportal.service.GenericAssayService; +import org.cbioportal.service.MolecularDataService; +import org.cbioportal.service.MolecularProfileService; +import org.cbioportal.service.MutationService; +import org.cbioportal.service.SignificantCopyNumberRegionService; +import org.cbioportal.service.SignificantlyMutatedGeneService; +import org.cbioportal.service.StudyViewService; import org.cbioportal.service.exception.MolecularProfileNotFoundException; import org.cbioportal.service.exception.StudyNotFoundException; import org.cbioportal.service.util.MolecularProfileUtil; +import org.cbioportal.web.parameter.GeneIdType; +import org.cbioportal.web.parameter.Projection; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -21,37 +55,39 @@ @Service public class StudyViewServiceImpl implements StudyViewService { private static final List CNA_TYPES_AMP_AND_HOMDEL = Collections.unmodifiableList(Arrays.asList(CNA.AMP, CNA.HOMDEL)); + private final MolecularProfileService molecularProfileService; + private final GenePanelService genePanelService; + private final MolecularProfileUtil molecularProfileUtil; + private final AlterationCountService alterationCountService; + private final SignificantlyMutatedGeneService significantlyMutatedGeneService; + private final SignificantCopyNumberRegionService significantCopyNumberRegionService; + private final GenericAssayService genericAssayService; + private final GeneService geneService; + private final MolecularDataService molecularDataService; + private final MutationService mutationService; + + // constructor dependency injections @Autowired - private MolecularProfileService molecularProfileService; - @Autowired - private GenePanelService genePanelService; - @Autowired - private MolecularProfileUtil molecularProfileUtil; - @Autowired - private AlterationCountService alterationCountService; - @Autowired - private SignificantlyMutatedGeneService significantlyMutatedGeneService; - @Autowired - private SignificantCopyNumberRegionService significantCopyNumberRegionService; - @Autowired - private GenericAssayService genericAssayService; - - @Autowired - private AlterationRepository alterationRepository; + public StudyViewServiceImpl(MolecularProfileService molecularProfileService, GenePanelService genePanelService, MolecularProfileUtil molecularProfileUtil, AlterationCountService alterationCountService, SignificantlyMutatedGeneService significantlyMutatedGeneService, SignificantCopyNumberRegionService significantCopyNumberRegionService, GenericAssayService genericAssayService, GeneService geneService, MolecularDataService molecularDataService, MutationService mutationService) { + this.molecularProfileService = molecularProfileService; + this.genePanelService = genePanelService; + this.molecularProfileUtil = molecularProfileUtil; + this.alterationCountService = alterationCountService; + this.significantlyMutatedGeneService = significantlyMutatedGeneService; + this.significantCopyNumberRegionService = significantCopyNumberRegionService; + this.genericAssayService = genericAssayService; + this.geneService = geneService; + this.molecularDataService = molecularDataService; + this.mutationService = mutationService; + } - @Autowired - private GeneService geneService; - - @Autowired - private MolecularDataService molecularDataService; - @Override public List getGenomicDataCounts(List studyIds, List sampleIds) { List molecularProfileSampleIdentifiers = molecularProfileService.getMolecularProfileCaseIdentifiers(studyIds, sampleIds); List molecularProfiles = molecularProfileService - .getMolecularProfilesInStudies(new ArrayList<>(new HashSet<>(studyIds)),"SUMMARY"); + .getMolecularProfilesInStudies(new ArrayList<>(new HashSet<>(studyIds)), Projection.SUMMARY.name()); Map molecularProfileMap = molecularProfiles .stream() .collect(Collectors.toMap(MolecularProfile::getStableId, Function.identity())); @@ -63,8 +99,8 @@ public List getGenomicDataCounts(List studyIds, List entry.getKey(), entry -> (int)entry.getValue().stream().map(d -> molecularProfileMap.get(entry.getKey()).getPatientLevel() ? d.getPatientId() : d.getSampleId()).distinct().count())); - + .collect(Collectors.toMap(Map.Entry::getKey, entry -> (int) entry.getValue().stream().map(d -> molecularProfileMap.get(entry.getKey()).getPatientLevel() ? d.getPatientId() : d.getSampleId()).distinct().count())); + return molecularProfileUtil .categorizeMolecularProfilesByStableIdSuffixes(molecularProfiles) .entrySet() @@ -84,7 +120,7 @@ public List getGenomicDataCounts(List studyIds, List dataCount.getCount() > 0) - .collect(Collectors.toList()); + .toList(); } @Override @@ -104,6 +140,118 @@ public List getMutationAlterationCountByGenes(List getMutationCountsByGeneSpecific(List studyIds, + List sampleIds, + List> genomicDataFilters, + AlterationFilter alterationFilter) { + List caseIdentifiers = + molecularProfileService.getMutationProfileCaseIdentifiers(studyIds, sampleIds); + + Set hugoGeneSymbols = genomicDataFilters.stream().map(Pair::getKey) + .collect(Collectors.toSet()); + + List entrezGeneIds = geneService + .fetchGenes(new ArrayList<>(hugoGeneSymbols), GeneIdType.HUGO_GENE_SYMBOL.name(), + Projection.SUMMARY.name()) + .stream() + .map(Gene::getEntrezGeneId) + .toList(); + + List alterationCountByGenes = alterationCountService.getSampleMutationGeneCounts( + caseIdentifiers, + Select.byValues(entrezGeneIds), + true, + false, + alterationFilter).getFirst(); + + return genomicDataFilters + .stream() + .flatMap(gdFilter -> { + GenomicDataCountItem genomicDataCountItem = new GenomicDataCountItem(); + String hugoGeneSymbol = gdFilter.getKey(); + String profileType = gdFilter.getValue(); + genomicDataCountItem.setHugoGeneSymbol(hugoGeneSymbol); + genomicDataCountItem.setProfileType(profileType); + + Optional filteredAlterationCount = alterationCountByGenes + .stream() + .filter(g -> StringUtils.isNotEmpty(g.getHugoGeneSymbol()) && g.getHugoGeneSymbol().equals(hugoGeneSymbol)) + .findFirst(); + + int totalCount = sampleIds.size(); + int mutatedCount = 0; + int profiledCount = 0; + + if(filteredAlterationCount.isPresent()) { + mutatedCount = filteredAlterationCount.get().getNumberOfAlteredCases(); + profiledCount = filteredAlterationCount.get().getNumberOfProfiledCases(); + } + + List genomicDataCounts = new ArrayList<>(); + + GenomicDataCount genomicDataCountMutated = new GenomicDataCount(); + genomicDataCountMutated.setLabel(MutationFilterOption.MUTATED.getSelectedOption()); + genomicDataCountMutated.setValue(MutationFilterOption.MUTATED.name()); + genomicDataCountMutated.setCount(mutatedCount); + genomicDataCountMutated.setUniqueCount(mutatedCount); + if (genomicDataCountMutated.getCount() > 0) genomicDataCounts.add(genomicDataCountMutated); + + GenomicDataCount genomicDataCountWildType = new GenomicDataCount(); + genomicDataCountWildType.setLabel(MutationFilterOption.NOT_MUTATED.getSelectedOption()); + genomicDataCountWildType.setValue(MutationFilterOption.NOT_MUTATED.name()); + genomicDataCountWildType.setCount(profiledCount - mutatedCount); + genomicDataCountWildType.setUniqueCount(profiledCount - mutatedCount); + if (genomicDataCountWildType.getCount() > 0) genomicDataCounts.add(genomicDataCountWildType); + + GenomicDataCount genomicDataCountNotProfiled = new GenomicDataCount(); + genomicDataCountNotProfiled.setLabel(MutationFilterOption.NOT_PROFILED.getSelectedOption()); + genomicDataCountNotProfiled.setValue(MutationFilterOption.NOT_PROFILED.name()); + genomicDataCountNotProfiled.setCount(totalCount - profiledCount); + genomicDataCountNotProfiled.setUniqueCount(totalCount - profiledCount); + if (genomicDataCountNotProfiled.getCount() > 0) genomicDataCounts.add(genomicDataCountNotProfiled); + + genomicDataCountItem.setCounts(genomicDataCounts); + + return Stream.of(genomicDataCountItem); + }).toList(); + } + + @Override + public List getMutationTypeCountsByGeneSpecific(List studyIds, + List sampleIds, + List> genomicDataFilters) { + Set hugoGeneSymbols = genomicDataFilters.stream().map(Pair::getKey) + .collect(Collectors.toSet()); + + Map geneSymbolIdMap = geneService + .fetchGenes(new ArrayList<>(hugoGeneSymbols), GeneIdType.HUGO_GENE_SYMBOL.name(), + Projection.SUMMARY.name()) + .stream().collect(Collectors.toMap(Gene::getHugoGeneSymbol, Gene::getEntrezGeneId)); + + return genomicDataFilters + .stream() + .flatMap(gdFilter -> { + String hugoGeneSymbol = gdFilter.getKey(); + String profileType = gdFilter.getValue(); + + List stableIds = Collections.singletonList(geneSymbolIdMap.get(hugoGeneSymbol)); + + Pair, List> sampleAndProfileIds = getMappedSampleAndProfileIds(studyIds, sampleIds, profileType); + List mappedSampleIds = sampleAndProfileIds.getFirst(); + List mappedProfileIds = sampleAndProfileIds.getSecond(); + + if (mappedSampleIds.isEmpty() || mappedProfileIds.isEmpty()) { + return Stream.of(); + } + + GenomicDataCountItem genomicDataCountItem = mutationService.getMutationCountsByType(mappedProfileIds, + mappedSampleIds, stableIds, profileType); + + return Stream.ofNullable(genomicDataCountItem); + }).toList(); + } + @Override public List getStructuralVariantAlterationCountByGenes(List studyIds, List sampleIds, @@ -139,12 +287,12 @@ private void annotateDataWithQValue(List studyIds, List mutSigMap = significantlyMutatedGeneService.getSignificantlyMutatedGenes( - studyIds.get(0), - "SUMMARY", - null, - null, - null, - null) + studyIds.get(0), + Projection.SUMMARY.name(), + null, + null, + null, + null) .stream() .collect(Collectors.toMap(MutSig::getEntrezGeneId, Function.identity())); alterationCountByGenes.forEach(r -> { @@ -162,7 +310,7 @@ public List getCNAAlterationCountByGenes(List stu throws StudyNotFoundException { List caseIdentifiers = molecularProfileService.getFirstDiscreteCNAProfileCaseIdentifiers(studyIds, sampleIds); - + List copyNumberCountByGenes = alterationCountService.getSampleCnaGeneCounts( caseIdentifiers, Select.all(), @@ -173,7 +321,7 @@ public List getCNAAlterationCountByGenes(List stu if (distinctStudyIds.size() == 1 && !copyNumberCountByGenes.isEmpty()) { List gisticList = significantCopyNumberRegionService.getSignificantCopyNumberRegions( studyIds.get(0), - "SUMMARY", + Projection.SUMMARY.name(), null, null, null, @@ -195,24 +343,17 @@ public List getCNAAlterationCountByGenes(List stu } @Override - public List getCNAAlterationCountsByGeneSpecific(List studyIds, + public List getCNAAlterationCountsByGeneSpecific(List studyIds, List sampleIds, List> genomicDataFilters) { - - List molecularProfiles = molecularProfileService.getMolecularProfilesInStudies(studyIds, - "SUMMARY"); - - Map> molecularProfileMap = molecularProfileUtil - .categorizeMolecularProfilesByStableIdSuffixes(molecularProfiles); - Set hugoGeneSymbols = genomicDataFilters.stream().map(Pair::getKey) .collect(Collectors.toSet()); Map geneSymbolIdMap = geneService - .fetchGenes(new ArrayList<>(hugoGeneSymbols), "HUGO_GENE_SYMBOL", - "SUMMARY") + .fetchGenes(new ArrayList<>(hugoGeneSymbols), GeneIdType.HUGO_GENE_SYMBOL.name(), + Projection.SUMMARY.name()) .stream().collect(Collectors.toMap(Gene::getHugoGeneSymbol, Gene::getEntrezGeneId)); - + return genomicDataFilters .stream() .flatMap(gdFilter -> { @@ -221,32 +362,20 @@ public List getCNAAlterationCountsByGeneSpecific(List stableIds = Arrays.asList(geneSymbolIdMap.get(hugoGeneSymbol).toString()); - Map studyIdToMolecularProfileIdMap = molecularProfileMap - .getOrDefault(profileType, new ArrayList()).stream() - .collect(Collectors.toMap(MolecularProfile::getCancerStudyIdentifier, - MolecularProfile::getStableId)); - - List mappedSampleIds = new ArrayList<>(); - List mappedProfileIds = new ArrayList<>(); - - for (int i = 0; i < sampleIds.size(); i++) { - String studyId = studyIds.get(i); - if (studyIdToMolecularProfileIdMap.containsKey(studyId)) { - mappedSampleIds.add(sampleIds.get(i)); - mappedProfileIds.add(studyIdToMolecularProfileIdMap.get(studyId)); - } - } + List stableIds = List.of(geneSymbolIdMap.get(hugoGeneSymbol).toString()); + + Pair, List> sampleAndProfileIds = getMappedSampleAndProfileIds(studyIds, sampleIds, profileType); + List mappedSampleIds = sampleAndProfileIds.getFirst(); + List mappedProfileIds = sampleAndProfileIds.getSecond(); if (mappedSampleIds.isEmpty()) { return Stream.of(); } List geneMolecularDataList = molecularDataService.getMolecularDataInMultipleMolecularProfiles(mappedProfileIds, mappedSampleIds, - stableIds.stream().map(Integer::parseInt).collect(Collectors.toList()), "SUMMARY"); - + stableIds.stream().map(Integer::parseInt).toList(), Projection.SUMMARY.name()); + List genomicDataCounts = geneMolecularDataList .stream() .filter(g -> StringUtils.isNotEmpty(g.getValue()) && !g.getValue().equals("NA")) @@ -270,7 +399,7 @@ public List getCNAAlterationCountsByGeneSpecific(List 0) { GenomicDataCount genomicDataCount = new GenomicDataCount(); genomicDataCount.setLabel("NA"); @@ -278,51 +407,31 @@ public List getCNAAlterationCountsByGeneSpecific(List fetchGenericAssayDataCounts(List sampleIds, List studyIds, - List stableIds, List profileTypes) { + List stableIds, List profileTypes) { if (stableIds.isEmpty()) { return new ArrayList<>(); } - // Get data from fetchGenericAssayData service - List molecularProfiles = molecularProfileService.getMolecularProfilesInStudies(studyIds, - "SUMMARY"); - - Map> molecularProfileMap = molecularProfileUtil - .categorizeMolecularProfilesByStableIdSuffixes(molecularProfiles); - List data = profileTypes.stream().flatMap(profileType -> { - // We need to create a map for mapping from studyId to profileId - Map studyIdToMolecularProfileIdMap = molecularProfileMap - .getOrDefault(profileType, new ArrayList<>()) - .stream().collect(Collectors.toMap(MolecularProfile::getCancerStudyIdentifier, - MolecularProfile::getStableId)); - - List mappedSampleIds = new ArrayList<>(); - List mappedProfileIds = new ArrayList<>(); - - for (int i = 0; i < sampleIds.size(); i++) { - String studyId = studyIds.get(i); - if (studyIdToMolecularProfileIdMap.containsKey(studyId)) { - mappedSampleIds.add(sampleIds.get(i)); - mappedProfileIds.add(studyIdToMolecularProfileIdMap.get(studyId)); - } - } + Pair, List> sampleAndProfileIds = getMappedSampleAndProfileIds(studyIds, sampleIds, profileType); + List mappedSampleIds = sampleAndProfileIds.getFirst(); + List mappedProfileIds = sampleAndProfileIds.getSecond(); try { - return genericAssayService.fetchGenericAssayData(mappedProfileIds, mappedSampleIds, stableIds, "SUMMARY").stream(); + return genericAssayService.fetchGenericAssayData(mappedProfileIds, mappedSampleIds, stableIds, Projection.SUMMARY.name()).stream(); } catch (MolecularProfileNotFoundException e) { return new ArrayList().stream(); } - }).collect(Collectors.toList()); - + }).toList(); + return data .stream() .filter(g -> StringUtils.isNotEmpty(g.getValue()) && !g.getValue().equals("NA")) @@ -341,10 +450,9 @@ public List fetchGenericAssayDataCounts(List GenericAssayDataCount dataCount = new GenericAssayDataCount(); dataCount.setValue(datum.getKey()); dataCount.setCount(datum.getValue().size()); - return dataCount; - }) - .collect(Collectors.toList()); - + return dataCount; + }).collect(Collectors.toList()); + if (naCount > 0) { GenericAssayDataCount dataCount = new GenericAssayDataCount(); dataCount.setValue("NA"); @@ -356,7 +464,34 @@ public List fetchGenericAssayDataCounts(List genericAssayDataCountItem.setStableId(entry.getKey()); genericAssayDataCountItem.setCounts(counts); return genericAssayDataCountItem; - }) - .collect(Collectors.toList()); + }).toList(); + } + + private Pair, List> getMappedSampleAndProfileIds(List studyIds, List sampleIds, String profileType) { + List molecularProfiles = molecularProfileService.getMolecularProfilesInStudies(studyIds, + Projection.SUMMARY.name()); + + Map> molecularProfileMap = molecularProfileUtil + .categorizeMolecularProfilesByStableIdSuffixes(molecularProfiles); + + Map studyIdToMolecularProfileIdMap = molecularProfileMap + .getOrDefault(profileType, new ArrayList()).stream() + .collect(Collectors.toMap(MolecularProfile::getCancerStudyIdentifier, + MolecularProfile::getStableId)); + + List mappedSampleIds = new ArrayList<>(); + List mappedProfileIds = new ArrayList<>(); + + for (int i = 0; i < sampleIds.size(); i++) { + String studyId = studyIds.get(i); + + // add samples only if the studyId is existed in the map + if (studyIdToMolecularProfileIdMap.containsKey(studyId)) { + mappedSampleIds.add(sampleIds.get(i)); + mappedProfileIds.add(studyIdToMolecularProfileIdMap.get(studyId)); + } + } + + return new Pair<>(mappedSampleIds, mappedProfileIds); } } diff --git a/src/main/java/org/cbioportal/service/impl/UnauthDataAccessTokenServiceImpl.java b/src/main/java/org/cbioportal/service/impl/UnauthDataAccessTokenServiceImpl.java index 527f7ef74b6..11cb8749223 100644 --- a/src/main/java/org/cbioportal/service/impl/UnauthDataAccessTokenServiceImpl.java +++ b/src/main/java/org/cbioportal/service/impl/UnauthDataAccessTokenServiceImpl.java @@ -48,7 +48,7 @@ * @author ochoaa */ @Component -@ConditionalOnProperty(name = "authenticate", havingValue = "none", matchIfMissing = true) +@ConditionalOnProperty(name = "dat.method", havingValue = "none", matchIfMissing = true) public class UnauthDataAccessTokenServiceImpl implements DataAccessTokenService { @Override diff --git a/src/main/java/org/cbioportal/service/util/MolecularProfileUtil.java b/src/main/java/org/cbioportal/service/util/MolecularProfileUtil.java index cfd80d4f28d..a9cbfa3839e 100644 --- a/src/main/java/org/cbioportal/service/util/MolecularProfileUtil.java +++ b/src/main/java/org/cbioportal/service/util/MolecularProfileUtil.java @@ -3,6 +3,7 @@ import org.cbioportal.model.MolecularProfile; import org.cbioportal.model.MolecularProfileCaseIdentifier; import org.springframework.stereotype.Component; + import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -35,27 +36,38 @@ public Map> categorizeMolecularProfilesByStableId molecularProfile.getStableId().replace(molecularProfile.getCancerStudyIdentifier() + "_", ""))); } + public List getFirstFilteredMolecularProfileCaseIdentifiers(List molecularProfiles, + List studyIds, + List sampleIds, + Optional> profileFilter) { + Map> mapByStudyId = getFilteredMolecularProfilesByStudyId(molecularProfiles, profileFilter); + List caseIdentifiers = new ArrayList<>(); + for (int studyIdIdx = 0; studyIdIdx < studyIds.size(); studyIdIdx++) { + String studyId = studyIds.get(studyIdIdx); + if (mapByStudyId.containsKey(studyId)) { + // only add identifier for one molecular profile + caseIdentifiers.add(new MolecularProfileCaseIdentifier(sampleIds.get(studyIdIdx), mapByStudyId.get(studyId).getFirst().getStableId())); + } + } + return caseIdentifiers; + } + public List getFilteredMolecularProfileCaseIdentifiers(List molecularProfiles, List studyIds, List sampleIds, Optional> profileFilter) { Map> mapByStudyId = getFilteredMolecularProfilesByStudyId(molecularProfiles, profileFilter); List caseIdentifiers = new ArrayList<>(); - for (int i = 0; i < studyIds.size(); i++) { - String studyId = studyIds.get(i); + for (int studyIdIdx = 0; studyIdIdx < studyIds.size(); studyIdIdx++) { + String studyId = studyIds.get(studyIdIdx); if (mapByStudyId.containsKey(studyId)) { - if (profileFilter.isPresent()) { - // only add identifier for one molecular profile - caseIdentifiers.add(new MolecularProfileCaseIdentifier(sampleIds.get(i), mapByStudyId.get(studyId).get(0).getStableId())); - } else { - // add case identifiers for all molecular profiles - int finalI = i; - mapByStudyId - .getOrDefault(studyId, new ArrayList<>()) - .forEach(molecularProfile -> { - caseIdentifiers.add(new MolecularProfileCaseIdentifier(sampleIds.get(finalI), molecularProfile.getStableId())); - }); - } + // add case identifiers for all molecular profiles + int finalStudyIdIdx = studyIdIdx; + mapByStudyId + .getOrDefault(studyId, new ArrayList<>()) + .forEach(molecularProfile -> + caseIdentifiers.add(new MolecularProfileCaseIdentifier(sampleIds.get(finalStudyIdIdx), molecularProfile.getStableId())) + ); } } return caseIdentifiers; diff --git a/src/main/java/org/cbioportal/service/util/ProfiledCasesCounter.java b/src/main/java/org/cbioportal/service/util/ProfiledCasesCounter.java index 3a4b3641df1..874a2cd0652 100644 --- a/src/main/java/org/cbioportal/service/util/ProfiledCasesCounter.java +++ b/src/main/java/org/cbioportal/service/util/ProfiledCasesCounter.java @@ -1,15 +1,26 @@ package org.cbioportal.service.util; -import java.util.*; -import java.util.function.Function; -import java.util.stream.Collectors; - import org.apache.commons.math3.util.Pair; -import org.cbioportal.model.*; +import org.cbioportal.model.AlterationCountBase; +import org.cbioportal.model.AlterationCountByGene; +import org.cbioportal.model.AlterationCountByStructuralVariant; +import org.cbioportal.model.GenePanel; +import org.cbioportal.model.GenePanelData; +import org.cbioportal.model.GenePanelToGene; import org.cbioportal.service.GenePanelService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + @Component public class ProfiledCasesCounter { @@ -20,14 +31,14 @@ public class ProfiledCasesCounter { Function patientUniqueIdentifier = sample -> sample.getStudyId() + sample.getPatientId(); private enum ProfiledCaseType { - SAMPLE, PATIENT; + SAMPLE, PATIENT } public void calculate(List alterationCounts, - List genePanelDataList, - boolean includeMissingAlterationsFromGenePanel, - Function caseUniqueIdentifier) { - + List genePanelDataList, + boolean includeMissingAlterationsFromGenePanel, + Function caseUniqueIdentifier) { + ProfiledCaseType profiledCaseType = (caseUniqueIdentifier == patientUniqueIdentifier) ? ProfiledCaseType.PATIENT : ProfiledCaseType.SAMPLE; Map> casesWithDataInGenePanel = extractCasesWithDataInGenePanel(genePanelDataList, caseUniqueIdentifier); @@ -55,28 +66,28 @@ public void calculate(List alterationCounts, } List genePanelData = genePanelDataList - .stream() - .filter(GenePanelData::getProfiled) - .collect(Collectors.toList()); + .stream() + .filter(GenePanelData::getProfiled) + .collect(Collectors.toList()); Set profiledCases = genePanelData - .stream() - // there can be duplicate patient or sample id, append study id - .map(caseUniqueIdentifier) - .collect(Collectors.toSet()); + .stream() + // there can be duplicate patient or sample id, append study id + .map(caseUniqueIdentifier) + .collect(Collectors.toSet()); int profiledCasesCount = profiledCases.size(); - + // here we look for cases where none of the profiles have gene panel ids // a case with at least one profile with gene panel id is considered as a case with gene panel data // so a case is considered without panel data only if none of the profiles has a gene panel id - + // first identify cases with gene panel data Set casesWithPanelData = genePanelData - .stream() - .filter(g -> g.getGenePanelId() != null) - // there can be duplicate patient or sample id, append study id - .map(caseUniqueIdentifier) - .collect(Collectors.toSet()); + .stream() + .filter(g -> g.getGenePanelId() != null) + // there can be duplicate patient or sample id, append study id + .map(caseUniqueIdentifier) + .collect(Collectors.toSet()); // find all unique cases Set casesWithoutPanelData = genePanelData @@ -87,7 +98,7 @@ public void calculate(List alterationCounts, // removing cases with panel data from all unique cases gives us the cases without panel data casesWithoutPanelData.removeAll(casesWithPanelData); - + for (T alterationCount : alterationCounts) { Set totalProfiledPatients = new HashSet<>(); Set allMatchingGenePanelIds = new HashSet<>(); @@ -122,8 +133,8 @@ public void calculate(List alterationCounts, if (includeMissingAlterationsFromGenePanel) { Set genesWithAlteration = alterationCounts.stream() - .flatMap(count -> Arrays.stream(count.getEntrezGeneIds())) - .collect(Collectors.toSet()); + .flatMap(count -> Arrays.stream(count.getEntrezGeneIds())) + .collect(Collectors.toSet()); geneToGenePanel.entrySet().forEach(entry -> { Integer entrezGeneId = entry.getKey().getFirst(); @@ -168,8 +179,8 @@ public void calculate(List alterationCounts, } private Map> extractCasesWithDataInGenePanel( - List genePanelDataList, - Function caseUniqueIdentifier) { + List genePanelDataList, + Function caseUniqueIdentifier) { Map> casesWithDataInGenePanel = new HashMap<>(); // loop through all membership records -- ignore any where g.getGenePanelId == null @@ -183,7 +194,7 @@ private Map> extractCasesWithDataInGenePanel( } return casesWithDataInGenePanel; } - + private boolean alterationIsCoveredByGenePanel(T alterationCount, Map, List> entrezIdToGenePanel) { return !getGenePanelsForAlterationCount(alterationCount, entrezIdToGenePanel).isEmpty(); } diff --git a/src/main/java/org/cbioportal/utils/config/PropertyCondition.java b/src/main/java/org/cbioportal/utils/config/PropertyCondition.java index 679343e0801..42a61f22f9b 100644 --- a/src/main/java/org/cbioportal/utils/config/PropertyCondition.java +++ b/src/main/java/org/cbioportal/utils/config/PropertyCondition.java @@ -43,7 +43,7 @@ @PropertySources({ @PropertySource(value="classpath:application.properties", ignoreResourceNotFound=true), - @PropertySource(value="file:///${PORTAL_HOME}/portal.properties", ignoreResourceNotFound=true) + @PropertySource(value="file:///${PORTAL_HOME}/application.properties", ignoreResourceNotFound=true) }) // Adapted from Spring Boot public class PropertyCondition implements Condition { diff --git a/src/main/java/org/cbioportal/web/CacheController.java b/src/main/java/org/cbioportal/web/CacheController.java index b739ef2b575..c86982c2b6f 100644 --- a/src/main/java/org/cbioportal/web/CacheController.java +++ b/src/main/java/org/cbioportal/web/CacheController.java @@ -43,7 +43,7 @@ public class CacheController { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = String.class))) public ResponseEntity clearAllCaches( - @Parameter(description = "Secret API key passed in HTTP header. The key is configured in portal.properties of the portal instance.") + @Parameter(description = "Secret API key passed in HTTP header. The key is configured in application.properties of the portal instance.") @RequestHeader(value = "X-API-KEY") String providedApiKey, @Parameter(description = "Clear Spring-managed caches") @RequestParam(defaultValue = "true", required = false) final boolean springManagedCache) @@ -63,7 +63,7 @@ public ResponseEntity clearAllCaches( @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = String.class))) public ResponseEntity clearCachesForStudy( - @Parameter(description = "Secret API key passed in HTTP header. The key is configured in portal.properties of the portal instance.") + @Parameter(description = "Secret API key passed in HTTP header. The key is configured in application.properties of the portal instance.") @RequestHeader(value = "X-API-KEY") String providedApiKey, @PathVariable String studyId, @Parameter(description = "Clear Spring-managed caches") diff --git a/src/main/java/org/cbioportal/web/DataAccessTokenController.java b/src/main/java/org/cbioportal/web/DataAccessTokenController.java index fb39a98b326..ca3681d1aec 100644 --- a/src/main/java/org/cbioportal/web/DataAccessTokenController.java +++ b/src/main/java/org/cbioportal/web/DataAccessTokenController.java @@ -35,7 +35,6 @@ import org.cbioportal.web.config.annotation.InternalApi; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -43,16 +42,15 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.HttpClientErrorException; import java.io.IOException; -import java.util.Arrays; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.Set; @InternalApi @@ -62,13 +60,42 @@ @Tag(name = "Data Access Tokens", description = " ") public class DataAccessTokenController { + @Value("${dat.unauth_users:anonymousUser}") + private String usersWhoCannotUseTokens; + + private String userRoleToAccessToken; + @Value("${download_group:}") // default is empty string + public void setUserRoleToAccessToken(String property) { userRoleToAccessToken = property; } + + private final DataAccessTokenService tokenService; + private final Set usersWhoCannotUseTokenSet; + + private static final String FILE_NAME = "cbioportal_data_access_token.txt"; + + @Autowired + public DataAccessTokenController(DataAccessTokenService tokenService) { + this.tokenService = tokenService; + if(Objects.isNull(usersWhoCannotUseTokens)) { + usersWhoCannotUseTokens = ""; + } + usersWhoCannotUseTokenSet = new HashSet<>(List.of((usersWhoCannotUseTokens.split(",")))); + } + @RequestMapping(method = RequestMethod.GET, value = "/api/data-access-token") @Operation(description = "Create a new data access token") @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = String.class))) public ResponseEntity downloadDataAccessToken(Authentication authentication, - HttpServletRequest request, HttpServletResponse response) throws IOException { - throw new UnsupportedOperationException("this endpoint is only enabled when dat is set to oauth2."); + HttpServletRequest request, HttpServletResponse response) { + // for other methods add header to trigger download of the token by the browser + response.setHeader("Content-Disposition", "attachment; filename=" + FILE_NAME); + String userName = getAuthenticatedUser(authentication); + DataAccessToken token = tokenService.createDataAccessToken(userName); + if (token == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + + return new ResponseEntity<>(token.toString(), HttpStatus.CREATED); } // retrieve and trigger download OAuth2 offline token @@ -85,7 +112,12 @@ public ResponseEntity downloadOAuth2DataAccessToken(HttpServletRequest r @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = DataAccessToken.class))) public ResponseEntity createDataAccessToken(Authentication authentication) throws HttpClientErrorException { - throw new UnsupportedOperationException("this endpoint is only enabled when dat is set to oauth2."); + String userName = getAuthenticatedUser(authentication); + DataAccessToken token = tokenService.createDataAccessToken(userName); + if (token == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<>(token, HttpStatus.CREATED); } @RequestMapping(method = RequestMethod.GET, value = "/api/data-access-tokens") @@ -94,7 +126,9 @@ public ResponseEntity createDataAccessToken(Authentication auth content = @Content(array = @ArraySchema(schema = @Schema(implementation = DataAccessToken.class)))) public ResponseEntity> getAllDataAccessTokens(HttpServletRequest request, Authentication authentication) { - throw new UnsupportedOperationException("this endpoint is only enabled when dat is set to oauth2."); + String userName = getAuthenticatedUser(authentication); + List allDataAccessTokens = tokenService.getAllDataAccessTokens(userName); + return new ResponseEntity<>(allDataAccessTokens, HttpStatus.OK); } @RequestMapping(method = RequestMethod.GET, value = "/api/data-access-tokens/{token}") @@ -103,19 +137,34 @@ public ResponseEntity> getAllDataAccessTokens(HttpServletR content = @Content(schema = @Schema(implementation = DataAccessToken.class))) public ResponseEntity getDataAccessToken( @Parameter(required = true, description = "token") @PathVariable String token) { - throw new UnsupportedOperationException("this endpoint is only enabled when dat is set to oauth2."); - + DataAccessToken dataAccessToken = tokenService.getDataAccessTokenInfo(token); + return new ResponseEntity<>(dataAccessToken, HttpStatus.OK); } @RequestMapping(method = RequestMethod.DELETE, value = "/api/data-access-tokens") @Operation(description = "Delete all data access tokens") public void revokeAllDataAccessTokens(Authentication authentication) { - throw new UnsupportedOperationException("this endpoint is does not apply to OAuth2 data access token method."); + tokenService.revokeAllDataAccessTokens(getAuthenticatedUser(authentication)); } @RequestMapping(method = RequestMethod.DELETE, value = "/api/data-access-tokens/{token}") @Operation(description = "Delete a data access token") public void revokeDataAccessToken(@Parameter(required = true, description = "token") @PathVariable String token) { - throw new UnsupportedOperationException("this endpoint is does not apply to OAuth2 data access token method."); + tokenService.revokeDataAccessToken(token); + } + + private String getAuthenticatedUser(Authentication authentication) { + if (authentication == null || !authentication.isAuthenticated()) { + throw new DataAccessTokenNoUserIdentityException(); + } + String username = authentication.getName(); + if (usersWhoCannotUseTokenSet.contains(username)) { + throw new DataAccessTokenProhibitedUserException(); + } + if(StringUtils.isNotEmpty(userRoleToAccessToken) && + !authentication.getAuthorities().contains(new SimpleGrantedAuthority(userRoleToAccessToken))) { + throw new DataAccessTokenProhibitedUserException(); + } + return username; } } diff --git a/src/main/java/org/cbioportal/web/IndexPageController.java b/src/main/java/org/cbioportal/web/IndexPageController.java index 5c432ef6b17..322e399d5a4 100644 --- a/src/main/java/org/cbioportal/web/IndexPageController.java +++ b/src/main/java/org/cbioportal/web/IndexPageController.java @@ -8,28 +8,21 @@ import com.fasterxml.jackson.databind.module.SimpleModule; import jakarta.servlet.http.HttpServletRequest; import org.cbioportal.service.FrontendPropertiesService; +import org.cbioportal.service.util.MskWholeSlideViewerTokenGenerator; import org.cbioportal.web.util.HttpRequestUtils; import org.json.simple.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.client.registration.ClientRegistration; -import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; -import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository; -import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import static org.cbioportal.service.FrontendPropertiesServiceImpl.FrontendProperty; @@ -50,6 +43,9 @@ public class IndexPageController { @Value("${saml.idp.metadata.entityid:not_defined_in_portalproperties}") private String samlIdpEntityId; + @Value("${msk.whole.slide.viewer.secret.key:}") + private String wholeSlideViewerKey; + private final ObjectMapper mapper = new ObjectMapper(); private Map getFrontendProperties(HttpServletRequest request, Authentication authentication) { @@ -59,8 +55,28 @@ private Map getFrontendProperties(HttpServletRequest request, Au properties.put("user_email_address", authentication != null ? authentication.getName(): "anonymousUser"); // TODO: Support skin.user_display_name properties.put("user_display_name", authentication != null ? authentication.getName(): "anonymousUser"); + // Set MSK slide viewer token at runtime + properties.put("mskWholeSlideViewerToken", getMskWholeSlideViewerToken(wholeSlideViewerKey, authentication)); return properties; } + + private String getMskWholeSlideViewerToken(String secretKey, Authentication authentication) { + // this token is for the msk portal + // the token is generated based on users' timestamp to let the slide viewer know whether the token is expired and then decide whether to allow the user to login the viewer + // every time when we refresh the page or goto the new page, a new token should be generated + if (secretKey != null) + secretKey = secretKey.trim(); + String timeStamp = String.valueOf(System.currentTimeMillis()); + + if (authentication != null && authentication.isAuthenticated() && secretKey != null && + !secretKey.isEmpty()) { + return "{ \"token\":\"" + MskWholeSlideViewerTokenGenerator.generateTokenByHmacSHA256( + authentication.getName(), secretKey, timeStamp) + "\", \"time\":\"" + timeStamp + + "\"}"; + } else { + return null; + } + } @RequestMapping({"/", "/index", "/index.html", "/study/summary", "/results" }) public String showIndexPage(HttpServletRequest request, Authentication authentication, Model model) diff --git a/src/main/java/org/cbioportal/web/InfoController.java b/src/main/java/org/cbioportal/web/InfoController.java index dbb36c8f640..59e9352ca5b 100644 --- a/src/main/java/org/cbioportal/web/InfoController.java +++ b/src/main/java/org/cbioportal/web/InfoController.java @@ -29,34 +29,34 @@ public class InfoController { @Value("${db.version}") private String dbVersion; - @Value("${git.branch}") + @Value("${git.branch:not set}") private String gitBranch; - @Value("${git.commit.id.full}") + @Value("${git.commit.id.full:not set}") private String gitCommitId; - @Value("${git.commit.id.abbrev}") + @Value("${git.commit.id.abbrev:not set}") private String gitCommitIdAbbrev; - @Value("${git.commit.id.describe}") + @Value("${git.commit.id.describe:not set}") private String gitCommitIdDescribe; - @Value("${git.commit.id.describe-short}") + @Value("${git.commit.id.describe-short:not set}") private String gitCommitIdDescribeShort; - @Value("${git.commit.message.full}") + @Value("${git.commit.message.full:not set}") private String gitCommitMessageFull; - @Value("${git.commit.message.short}") + @Value("${git.commit.message.short:not set}") private String gitCommitMessageShort; - @Value("${git.commit.user.email}") + @Value("${git.commit.user.email:not set}") private String gitCommitMessageUserEmail; - @Value("${git.commit.user.name}") + @Value("${git.commit.user.name:not set}") private String gitCommitMessageUserName; - @Value("${git.dirty}") + @Value("${git.dirty:not set}") private String gitDirty; @RequestMapping(value = "/api/info", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) diff --git a/src/main/java/org/cbioportal/web/LegacyApiController.java b/src/main/java/org/cbioportal/web/LegacyApiController.java new file mode 100644 index 00000000000..6e696460b59 --- /dev/null +++ b/src/main/java/org/cbioportal/web/LegacyApiController.java @@ -0,0 +1,57 @@ +package org.cbioportal.web; + + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.lang.Nullable; +import org.springframework.util.FileCopyUtils; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.Objects; + +@RestController +public class LegacyApiController { + + private static final String JSON_HOST_KEY = "host"; + private static final String REQUEST_HEADER_HOST = "Host"; + private static final String LEGACY_API_FILE_JSON = "legacy-api.json"; + + @Nullable private String legacySwaggerJson; + + @GetMapping(value = "/api/v2/api-docs", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity getLegacyAPI(HttpServletRequest request) throws IOException { + + if(Objects.isNull(legacySwaggerJson)) { + legacySwaggerJson = getLegacySwagger(request.getHeader(REQUEST_HEADER_HOST)); + } + return ResponseEntity.ok(legacySwaggerJson); + } + + private String getLegacySwagger(String host) throws IOException { + Resource resource = new ClassPathResource(LEGACY_API_FILE_JSON); + InputStreamReader reader = new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8); + + String jsonData = FileCopyUtils.copyToString(reader); + + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode jsonNode = objectMapper.readTree(jsonData); + + // Update key host + if(jsonNode.has(JSON_HOST_KEY)) { + ((ObjectNode) jsonNode).put(JSON_HOST_KEY, host); + } + + // Convert back to string + return objectMapper.writeValueAsString(jsonNode); + } +} diff --git a/src/main/java/org/cbioportal/web/LoginPageController.java b/src/main/java/org/cbioportal/web/LoginPageController.java index 4ffe9050e73..cadcdb10838 100644 --- a/src/main/java/org/cbioportal/web/LoginPageController.java +++ b/src/main/java/org/cbioportal/web/LoginPageController.java @@ -1,7 +1,6 @@ package org.cbioportal.web; import jakarta.servlet.http.HttpServletRequest; -import org.apache.commons.collections.map.HashedMap; import org.cbioportal.service.FrontendPropertiesService; import org.cbioportal.service.FrontendPropertiesServiceImpl; import org.slf4j.Logger; @@ -17,8 +16,8 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; -import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -36,26 +35,38 @@ public class LoginPageController { @Value("${authenticate}") private String authenticate; + + @Value("${security.force_redirect_on_one_idp:true}") + private boolean forceRedirectOnOneIdentityProvider; + @PostMapping(value = "/login", produces = MediaType.APPLICATION_JSON_VALUE) + public String showLoginPagePost(HttpServletRequest request, Authentication authentication, Model model) { + populateModel(request, model, new HashMap<>()); + return "login"; + } + @GetMapping(value = "/login", produces = MediaType.APPLICATION_JSON_VALUE) public String showLoginPage(HttpServletRequest request, Authentication authentication, Model model) { - Map oauth2AuthenticationUrls = getOauth2AuthenticationUrls(); - - model.addAttribute("oauth_urls", oauth2AuthenticationUrls); + boolean logoutFailure = request.getParameterMap().containsKey("logout_failure"); + if(oauth2AuthenticationUrls.size() == 1 && !logoutFailure && this.forceRedirectOnOneIdentityProvider) { + log.debug("Redirecting to Identity Provider"); + return "redirect:" + oauth2AuthenticationUrls.values().iterator().next(); + } + populateModel(request, model, oauth2AuthenticationUrls); + return "login"; + } + private void populateModel(HttpServletRequest request, Model model, Map oauth2AuthenticationUrls) { + model.addAttribute("oauth_urls", oauth2AuthenticationUrls); model.addAttribute("skin_title", frontendPropertiesService.getFrontendProperty(FrontendPropertiesServiceImpl.FrontendProperty.skin_title)); model.addAttribute("skin_authorization_message", frontendPropertiesService.getFrontendProperty(FrontendPropertiesServiceImpl.FrontendProperty.skin_authorization_message)); model.addAttribute("skin_login_contact_html", frontendPropertiesService.getFrontendProperty(FrontendPropertiesServiceImpl.FrontendProperty.skin_login_contact_html)); model.addAttribute("skin_login_saml_registration_html", frontendPropertiesService.getFrontendProperty(FrontendPropertiesServiceImpl.FrontendProperty.skin_login_saml_registration_html)); model.addAttribute("saml_idp_metadata_entityid", frontendPropertiesService.getFrontendProperty(FrontendPropertiesServiceImpl.FrontendProperty.saml_idp_metadata_entityid)); model.addAttribute("logout_success", request.getParameterMap().containsKey("logout_success")); - model.addAttribute("login_error", Boolean.parseBoolean(request.getParameter("login_error"))); + model.addAttribute("login_error", request.getParameterMap().containsKey("logout_failure")); model.addAttribute("show_saml", frontendPropertiesService.getFrontendProperty(FrontendPropertiesServiceImpl.FrontendProperty.authenticationMethod).equals("saml")); - model.addAttribute("show_google", Arrays.asList(authenticate).contains("social_auth") || Arrays.asList(authenticate).contains("social_auth_google") ); - model.addAttribute("show_microsoft", Arrays.asList(authenticate).contains("social_auth_microsoft")); - - return "login"; } private Map getOauth2AuthenticationUrls() { diff --git a/src/main/java/org/cbioportal/web/MskEntityTranslationController.java b/src/main/java/org/cbioportal/web/MskEntityTranslationController.java index d4a9063a514..38135ccc15a 100644 --- a/src/main/java/org/cbioportal/web/MskEntityTranslationController.java +++ b/src/main/java/org/cbioportal/web/MskEntityTranslationController.java @@ -61,8 +61,8 @@ */ @Controller @PropertySources({ - @PropertySource(value="classpath:portal.properties", ignoreResourceNotFound=true), - @PropertySource(value="file:///${PORTAL_HOME}/portal.properties", ignoreResourceNotFound=true) + @PropertySource(value="classpath:application.properties", ignoreResourceNotFound=true), + @PropertySource(value="file:///${PORTAL_HOME}/application.properties", ignoreResourceNotFound=true) }) @ConditionalOnProperty(name = "msk_entity_translation_enabled", havingValue = "true") public class MskEntityTranslationController { @@ -91,7 +91,7 @@ private static Pattern initDMPSampleIDPattern() { } @RequestMapping( - value={"/cis/{sampleID}", "/darwin/{sampleID}"}, + value={"/api-legacy/cis/{sampleID}", "/api-legacy/darwin/{sampleID}"}, method=RequestMethod.GET ) public ModelAndView redirectIMPACT(@PathVariable String sampleID, ModelMap model) { @@ -99,7 +99,7 @@ public ModelAndView redirectIMPACT(@PathVariable String sampleID, ModelMap model } @RequestMapping( - value="/crdb/{sampleID}", + value="/api-legacy/crdb/{sampleID}", method=RequestMethod.GET ) public ModelAndView redirectCRDB(@PathVariable String sampleID, ModelMap model) { @@ -132,7 +132,7 @@ private String getRedirectURL(String sampleID) { } @RequestMapping( - value={"/cis/{sampleID}/exists", "/darwin/{sampleID}/exists", "/crdb/{sampleID}/exists"}, + value={"/api-legacy/cis/{sampleID}/exists", "/api-legacy/darwin/{sampleID}/exists", "/api-legacy/crdb/{sampleID}/exists"}, method=RequestMethod.GET ) public @ResponseBody HashMap exists(@PathVariable String sampleID, ModelMap model) { diff --git a/src/main/java/org/cbioportal/web/MutationController.java b/src/main/java/org/cbioportal/web/MutationController.java index fc9c0b91ba0..7c72d36db41 100644 --- a/src/main/java/org/cbioportal/web/MutationController.java +++ b/src/main/java/org/cbioportal/web/MutationController.java @@ -91,7 +91,7 @@ public ResponseEntity> getMutationsInMolecularProfileBySampleList } else { return new ResponseEntity<>( mutationService.getMutationsInMolecularProfileBySampleListId(molecularProfileId, sampleListId, - entrezGeneId == null ? null : Arrays.asList(entrezGeneId), null, projection.name(), pageSize, + entrezGeneId == null ? null : Arrays.asList(entrezGeneId), false, projection.name(), pageSize, pageNumber, sortBy == null ? null : sortBy.getOriginalValue(), direction.name()), HttpStatus.OK); } } @@ -139,11 +139,11 @@ public ResponseEntity> fetchMutationsInMolecularProfile( List mutations; if (mutationFilter.getSampleListId() != null) { mutations = mutationService.getMutationsInMolecularProfileBySampleListId(molecularProfileId, - mutationFilter.getSampleListId(), mutationFilter.getEntrezGeneIds(), null, projection.name(), + mutationFilter.getSampleListId(), mutationFilter.getEntrezGeneIds(), false, projection.name(), pageSize, pageNumber, sortBy == null ? null : sortBy.getOriginalValue(), direction.name()); } else { mutations = mutationService.fetchMutationsInMolecularProfile(molecularProfileId, - mutationFilter.getSampleIds(), mutationFilter.getEntrezGeneIds(), null, projection.name(), pageSize, + mutationFilter.getSampleIds(), mutationFilter.getEntrezGeneIds(), false, projection.name(), pageSize, pageNumber, sortBy == null ? null : sortBy.getOriginalValue(), direction.name()); } diff --git a/src/main/java/org/cbioportal/web/SamlAndBasicLoginController.java b/src/main/java/org/cbioportal/web/SamlAndBasicLoginController.java new file mode 100644 index 00000000000..0364e0d981f --- /dev/null +++ b/src/main/java/org/cbioportal/web/SamlAndBasicLoginController.java @@ -0,0 +1,29 @@ +package org.cbioportal.web; + +import jakarta.servlet.http.HttpServletRequest; +import org.cbioportal.service.FrontendPropertiesService; +import org.cbioportal.service.FrontendPropertiesServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +@ConditionalOnProperty(value = "authenticate", havingValue = "saml_plus_basic") +public class SamlAndBasicLoginController { + + private final FrontendPropertiesService frontendPropertiesService; + + @Autowired + SamlAndBasicLoginController(FrontendPropertiesService frontendPropertiesService) { + this.frontendPropertiesService = frontendPropertiesService; + } + + @GetMapping(value = "/restful_login", produces = MediaType.APPLICATION_JSON_VALUE) + public String showRestfulLoginPage(HttpServletRequest request, Model model) { + model.addAttribute("skin_title", frontendPropertiesService.getFrontendProperty(FrontendPropertiesServiceImpl.FrontendProperty.skin_title)); + return "restful_login"; + } +} diff --git a/src/main/java/org/cbioportal/web/StudyController.java b/src/main/java/org/cbioportal/web/StudyController.java index d3cf9bc9b39..253b591719d 100644 --- a/src/main/java/org/cbioportal/web/StudyController.java +++ b/src/main/java/org/cbioportal/web/StudyController.java @@ -34,6 +34,7 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.access.prepost.PreFilter; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.validation.annotation.Validated; @@ -194,6 +195,7 @@ public ResponseEntity getTags( } @PreAuthorize("hasPermission(#studyIds, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") + @PreFilter("hasPermission(#studyIds, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") @RequestMapping(value = "/studies/tags/fetch", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(description = "Get the study tags by IDs") diff --git a/src/main/java/org/cbioportal/web/StudyViewController.java b/src/main/java/org/cbioportal/web/StudyViewController.java index 6ff98aa3ba1..8cf33037df3 100644 --- a/src/main/java/org/cbioportal/web/StudyViewController.java +++ b/src/main/java/org/cbioportal/web/StudyViewController.java @@ -63,6 +63,7 @@ import org.cbioportal.web.parameter.GenomicDataCountFilter; import org.cbioportal.web.parameter.GenomicDataFilter; import org.cbioportal.web.parameter.HeaderKeyConstants; +import org.cbioportal.web.parameter.MutationOption; import org.cbioportal.web.parameter.PagingConstants; import org.cbioportal.web.parameter.Projection; import org.cbioportal.web.parameter.SampleIdentifier; @@ -80,7 +81,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestAttribute; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -165,20 +165,20 @@ public ResponseEntity> fetchClinicalDataCounts( if (attributes.size() == 1) { studyViewFilterUtil.removeSelfFromFilter(attributes.get(0).getAttributeId(), studyViewFilter); } - boolean singleStudyUnfiltered = studyViewFilterUtil.isSingleStudyUnfiltered(studyViewFilter); - List result = - this.getInstance().cachedClinicalDataCounts(interceptedClinicalDataCountFilter,singleStudyUnfiltered); + boolean unfilteredQuery = studyViewFilterUtil.isUnfilteredQuery(studyViewFilter); + List result = + this.getInstance().cachedClinicalDataCounts(interceptedClinicalDataCountFilter, + unfilteredQuery); return new ResponseEntity<>(result, HttpStatus.OK); } - + @Cacheable( cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabled() && #singleStudyUnfiltered" + condition = "@cacheEnabledConfig.getEnabled() && #unfilteredQuery" ) - public List cachedClinicalDataCounts( - ClinicalDataCountFilter interceptedClinicalDataCountFilter, boolean singleStudyUnfiltered - ) { + public List cachedClinicalDataCounts(ClinicalDataCountFilter interceptedClinicalDataCountFilter, + boolean unfilteredQuery) { List attributes = interceptedClinicalDataCountFilter.getAttributes(); StudyViewFilter studyViewFilter = interceptedClinicalDataCountFilter.getStudyViewFilter(); if (attributes.size() == 1) { @@ -216,21 +216,22 @@ public ResponseEntity> fetchClinicalDataBinCounts( @Valid @RequestAttribute(required = false, value = "interceptedClinicalDataBinCountFilter") ClinicalDataBinCountFilter interceptedClinicalDataBinCountFilter ) { StudyViewFilter studyViewFilter = clinicalDataBinUtil.removeSelfFromFilter(interceptedClinicalDataBinCountFilter); - boolean singleStudyUnfiltered = studyViewFilterUtil.isSingleStudyUnfiltered(studyViewFilter); - List clinicalDataBins = - this.getInstance().cachableFetchClinicalDataBinCounts(dataBinMethod, interceptedClinicalDataBinCountFilter, singleStudyUnfiltered); + boolean unfilteredQuery = studyViewFilterUtil.isUnfilteredQuery(studyViewFilter); + List clinicalDataBins = + this.getInstance().cachableFetchClinicalDataBinCounts(dataBinMethod, + interceptedClinicalDataBinCountFilter, + unfilteredQuery); return new ResponseEntity<>(clinicalDataBins, HttpStatus.OK); } @Cacheable( cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabled() && #singleStudyUnfiltered" + condition = "@cacheEnabledConfig.getEnabled() && #unfilteredQuery" ) - public List cachableFetchClinicalDataBinCounts( - DataBinMethod dataBinMethod, - ClinicalDataBinCountFilter interceptedClinicalDataBinCountFilter, - boolean singleStudyUnfiltered + public List cachableFetchClinicalDataBinCounts(DataBinMethod dataBinMethod, + ClinicalDataBinCountFilter interceptedClinicalDataBinCountFilter, + boolean unfilteredQuery ) { return clinicalDataBinUtil.fetchClinicalDataBinCounts( dataBinMethod, @@ -287,18 +288,18 @@ public ResponseEntity> fetchMutatedGenes( @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface. this attribute is needed for the @PreAuthorize tag above. @Valid @RequestAttribute(required = false, value = "interceptedStudyViewFilter") StudyViewFilter interceptedStudyViewFilter ) throws StudyNotFoundException { - boolean singleStudyUnfiltered = studyViewFilterUtil.isSingleStudyUnfiltered(interceptedStudyViewFilter); - List alterationCountByGenes = this.getInstance().cachedFetchMutatedGenes(interceptedStudyViewFilter, singleStudyUnfiltered); + boolean unfilteredQuery = studyViewFilterUtil.isUnfilteredQuery(interceptedStudyViewFilter); + List alterationCountByGenes = this.getInstance().cachedFetchMutatedGenes(interceptedStudyViewFilter, + unfilteredQuery); return new ResponseEntity<>(alterationCountByGenes, HttpStatus.OK); } @Cacheable( cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabled() && #singleStudyUnfiltered" + condition = "@cacheEnabledConfig.getEnabled() && #unfilteredQuery" ) - public List cachedFetchMutatedGenes( - StudyViewFilter interceptedStudyViewFilter, boolean singleStudyUnfiltered - ) throws StudyNotFoundException { + public List cachedFetchMutatedGenes(StudyViewFilter interceptedStudyViewFilter, + boolean unfilteredQuery) throws StudyNotFoundException { AlterationFilter annotationFilters = interceptedStudyViewFilter.getAlterationFilter(); List sampleIdentifiers = studyViewFilterApplier.apply(interceptedStudyViewFilter); @@ -327,19 +328,19 @@ public ResponseEntity> fetchStructuralVariantGenes( @Valid @RequestAttribute(required = false, value = "interceptedStudyViewFilter") StudyViewFilter interceptedStudyViewFilter ) throws StudyNotFoundException { - boolean singleStudyUnfiltered = studyViewFilterUtil.isSingleStudyUnfiltered(interceptedStudyViewFilter); - List alterationCountByGenes = - this.getInstance().cacheableFetchStructuralVariantGenes(interceptedStudyViewFilter, singleStudyUnfiltered); + boolean unfilteredQuery = studyViewFilterUtil.isUnfilteredQuery(interceptedStudyViewFilter); + List alterationCountByGenes = + this.getInstance().cacheableFetchStructuralVariantGenes(interceptedStudyViewFilter, + unfilteredQuery); return new ResponseEntity<>(alterationCountByGenes, HttpStatus.OK); } @Cacheable( cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabled() && #singleStudyUnfiltered" + condition = "@cacheEnabledConfig.getEnabled() && #unfilteredQuery" ) - public List cacheableFetchStructuralVariantGenes( - StudyViewFilter interceptedStudyViewFilter, boolean singleStudyUnfiltered - ) throws StudyNotFoundException { + public List cacheableFetchStructuralVariantGenes(StudyViewFilter interceptedStudyViewFilter, + boolean unfilteredQuery) throws StudyNotFoundException { AlterationFilter annotationFilters = interceptedStudyViewFilter.getAlterationFilter(); List sampleIdentifiers = studyViewFilterApplier.apply(interceptedStudyViewFilter); @@ -368,19 +369,19 @@ public ResponseEntity> fetchStructuralV @Valid @RequestAttribute(required = false, value = "interceptedStudyViewFilter") StudyViewFilter interceptedStudyViewFilter ) throws StudyNotFoundException { - boolean singleStudyUnfiltered = studyViewFilterUtil.isSingleStudyUnfiltered(interceptedStudyViewFilter); - List alterationCountByStructuralVariants = - this.getInstance().cacheableFetchStructuralVariantCounts(interceptedStudyViewFilter, singleStudyUnfiltered); + boolean unfilteredQuery = studyViewFilterUtil.isUnfilteredQuery(interceptedStudyViewFilter); + List alterationCountByStructuralVariants = + this.getInstance().cacheableFetchStructuralVariantCounts(interceptedStudyViewFilter, + unfilteredQuery); return new ResponseEntity<>(alterationCountByStructuralVariants, HttpStatus.OK); } @Cacheable( cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabled() && #singleStudyUnfiltered" + condition = "@cacheEnabledConfig.getEnabled() && #unfilteredQuery" ) - public List cacheableFetchStructuralVariantCounts( - StudyViewFilter interceptedStudyViewFilter, boolean singleStudyUnfiltered - ) throws StudyNotFoundException { + public List cacheableFetchStructuralVariantCounts(StudyViewFilter interceptedStudyViewFilter, + boolean unfilteredQuery) { List sampleIdentifiers = studyViewFilterApplier.apply(interceptedStudyViewFilter); if(CollectionUtils.isNotEmpty(sampleIdentifiers)) { @@ -406,16 +407,18 @@ public ResponseEntity> fetchCNAGenes( @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface. this attribute is needed for the @PreAuthorize tag above. @Valid @RequestAttribute(required = false, value = "interceptedStudyViewFilter") StudyViewFilter interceptedStudyViewFilter ) throws StudyNotFoundException { - boolean singleStudyUnfiltered = studyViewFilterUtil.isSingleStudyUnfiltered(interceptedStudyViewFilter); - List copyNumberCountByGenes = this.getInstance().cacheableFetchCNAGenes(interceptedStudyViewFilter, singleStudyUnfiltered); + boolean unfilteredQuery = studyViewFilterUtil.isUnfilteredQuery(interceptedStudyViewFilter); + List copyNumberCountByGenes = this.getInstance().cacheableFetchCNAGenes(interceptedStudyViewFilter, + unfilteredQuery); return new ResponseEntity<>(copyNumberCountByGenes, HttpStatus.OK); } @Cacheable( cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabled() && #singleStudyUnfiltered" + condition = "@cacheEnabledConfig.getEnabled() && #unfilteredQuery" ) - public List cacheableFetchCNAGenes(StudyViewFilter interceptedStudyViewFilter, boolean singleStudyUnfiltered) throws StudyNotFoundException { + public List cacheableFetchCNAGenes(StudyViewFilter interceptedStudyViewFilter, + boolean unfilteredQuery) throws StudyNotFoundException { AlterationFilter alterationFilter = interceptedStudyViewFilter.getAlterationFilter(); List sampleIdentifiers = studyViewFilterApplier.apply(interceptedStudyViewFilter); @@ -437,7 +440,7 @@ public List cacheableFetchCNAGenes(StudyViewFilter interc content = @Content(array = @ArraySchema(schema = @Schema(implementation = Sample.class)))) public ResponseEntity> fetchFilteredSamples( @Parameter(description = "Whether to negate the study view filters") - @RequestParam(defaultValue = "false") Boolean negateFilters, + @RequestParam(defaultValue = "false") boolean negateFilters, @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface. this attribute is needed for the @PreAuthorize tag above. @@ -473,18 +476,18 @@ public ResponseEntity> fetchMolecularProfileSampleCounts( @Valid @RequestAttribute(required = false, value = "interceptedStudyViewFilter") StudyViewFilter interceptedStudyViewFilter ) { - boolean singleStudyUnfiltered = studyViewFilterUtil.isSingleStudyUnfiltered(interceptedStudyViewFilter); - List sampleCounts = this.getInstance().cacheableFetchMolecularProfileSampleCounts(interceptedStudyViewFilter, singleStudyUnfiltered); + boolean unfilteredQuery = studyViewFilterUtil.isUnfilteredQuery(interceptedStudyViewFilter); + List sampleCounts = this.getInstance().cacheableFetchMolecularProfileSampleCounts(interceptedStudyViewFilter, + unfilteredQuery); return new ResponseEntity<>(sampleCounts, HttpStatus.OK); } @Cacheable( cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabled() && #singleStudyUnfiltered" + condition = "@cacheEnabledConfig.getEnabled() && #unfilteredQuery" ) - public List cacheableFetchMolecularProfileSampleCounts( - StudyViewFilter interceptedStudyViewFilter, boolean singleStudyUnfiltered - ) { + public List cacheableFetchMolecularProfileSampleCounts(StudyViewFilter interceptedStudyViewFilter, + boolean unfilteredQuery) { List sampleIdentifiers = studyViewFilterApplier.apply(interceptedStudyViewFilter); List genomicDataCounts = new ArrayList<>(); if(CollectionUtils.isNotEmpty(sampleIdentifiers)) { @@ -574,8 +577,8 @@ public ResponseEntity fetchClinicalDataDensityPlot( if (CollectionUtils.isNotEmpty(patientAttributeIds)) { List samples = sampleService.fetchSamples(studyIds, sampleIds, Projection.DETAILED.name()); List patients = patientService.getPatientsOfSamples(studyIds, sampleIds); - patientIds = patients.stream().map(Patient::getStableId).collect(Collectors.toList()); - studyIdsOfPatients = patients.stream().map(Patient::getCancerStudyIdentifier).collect(Collectors.toList()); + patientIds = patients.stream().map(Patient::getStableId).toList(); + studyIdsOfPatients = patients.stream().map(Patient::getCancerStudyIdentifier).toList(); patientToSamples = samples.stream().collect( Collectors.groupingBy(Sample::getPatientStableId, Collectors.groupingBy(Sample::getCancerStudyIdentifier)) ); @@ -807,8 +810,8 @@ public ResponseEntity fetchClinicalDataViolinPlots( if (CollectionUtils.isNotEmpty(patientAttributeIds)) { List samplesWithoutNumericalFilter = sampleService.fetchSamples(studyIdsWithoutNumericalFilter, sampleIdsWithoutNumericalFilter, Projection.DETAILED.name()); List patients = patientService.getPatientsOfSamples(studyIdsWithoutNumericalFilter, sampleIdsWithoutNumericalFilter); - patientIds = patients.stream().map(Patient::getStableId).collect(Collectors.toList()); - studyIdsOfPatients = patients.stream().map(Patient::getCancerStudyIdentifier).collect(Collectors.toList()); + patientIds = patients.stream().map(Patient::getStableId).toList(); + studyIdsOfPatients = patients.stream().map(Patient::getCancerStudyIdentifier).toList(); patientToSamples = samplesWithoutNumericalFilter.stream().collect( Collectors.groupingBy(Sample::getPatientStableId, Collectors.groupingBy(Sample::getCancerStudyIdentifier)) ); @@ -922,7 +925,7 @@ public List fetchCaseListCounts( return dataCount; }) .filter(dataCount -> dataCount.getCount() > 0) - .collect(Collectors.toList()); + .toList(); } @@ -1019,7 +1022,7 @@ public ResponseEntity> fetchGenericAssayDataCoun List result = studyViewService.fetchGenericAssayDataCounts( sampleIds, studyIds, - gaFilters.stream().map(GenericAssayDataFilter::getStableId).collect(Collectors.toList()), + gaFilters.stream().map(GenericAssayDataFilter::getStableId).toList(), gaFilters.stream().map(GenericAssayDataFilter::getProfileType).collect(Collectors.toList())); return new ResponseEntity<>(result, HttpStatus.OK); @@ -1110,9 +1113,9 @@ public ResponseEntity fetchClinicalDataClinicalTable( final List> patientIdentifiers = sampleClinicalData.stream() .map(d -> new ImmutablePair<>(d.getStudyId(), d.getPatientId())) .distinct() - .collect(Collectors.toList()); - List patientStudyIds = patientIdentifiers.stream().map(p -> p.getLeft()).collect(Collectors.toList()); - List patientIds = patientIdentifiers.stream().map(p -> p.getRight()).collect(Collectors.toList()); + .toList(); + List patientStudyIds = patientIdentifiers.stream().map(ImmutablePair::getLeft).toList(); + List patientIds = patientIdentifiers.stream().map(ImmutablePair::getRight).toList(); List searchAllAttributes = null; @@ -1149,22 +1152,78 @@ public ResponseEntity> getClinicalEventTypeCounts( @RequestAttribute(required = false, value = "interceptedStudyViewFilter") StudyViewFilter interceptedStudyViewFilter ) { - boolean singleStudyUnfiltered = studyViewFilterUtil.isSingleStudyUnfiltered(interceptedStudyViewFilter); - List eventTypeCounts = this.getInstance().cachedClinicalEventTypeCounts(interceptedStudyViewFilter, singleStudyUnfiltered); + boolean unfilteredQuery = studyViewFilterUtil.isUnfilteredQuery(interceptedStudyViewFilter); + List eventTypeCounts = this.getInstance().cachedClinicalEventTypeCounts(interceptedStudyViewFilter, + unfilteredQuery); return new ResponseEntity<>(eventTypeCounts, HttpStatus.OK); } @Cacheable( cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabled() && #singleStudyUnfiltered" + condition = "@cacheEnabledConfig.getEnabled() && #unfilteredQuery" ) - public List cachedClinicalEventTypeCounts( - StudyViewFilter interceptedStudyViewFilter, boolean singleStudyUnfiltered - ){ + public List cachedClinicalEventTypeCounts(StudyViewFilter interceptedStudyViewFilter, + boolean unfilteredQuery + ) { List filteredSampleIdentifiers = studyViewFilterApplier.apply(interceptedStudyViewFilter); List sampleIds = new ArrayList<>(); List studyIds = new ArrayList<>(); studyViewFilterUtil.extractStudyAndSampleIds(filteredSampleIdentifiers, studyIds, sampleIds); return clinicalEventService.getClinicalEventTypeCounts(studyIds, sampleIds); } + + @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") + @RequestMapping(value = "/mutation-data-counts/fetch", method = RequestMethod.POST, + consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(description = "Fetch mutation data counts by GenomicDataCountFilter") + public ResponseEntity> fetchMutationDataCounts( + @Parameter(description = "Level of detail of the response") + @RequestParam(defaultValue = "SUMMARY") Projection projection, + @Parameter(required = true, description = "Genomic data count filter") + @Valid @RequestBody(required = false) GenomicDataCountFilter genomicDataCountFilter, + @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface + @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, + @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface + @Valid @RequestAttribute(required = false, value = "interceptedGenomicDataCountFilter") GenomicDataCountFilter interceptedGenomicDataCountFilter + ) { + List gdFilters = interceptedGenomicDataCountFilter.getGenomicDataFilters(); + StudyViewFilter studyViewFilter = interceptedGenomicDataCountFilter.getStudyViewFilter(); + // when there is only one filter, it means study view is doing a single chart filter operation + // remove filter from studyViewFilter to return all data counts + // the reason we do this is to make sure after chart get filtered, user can still see unselected portion of the chart + if (gdFilters.size() == 1 && projection == Projection.SUMMARY) { + studyViewFilterUtil.removeSelfFromMutationDataFilter( + gdFilters.get(0).getHugoGeneSymbol(), + gdFilters.get(0).getProfileType(), + MutationOption.MUTATED, + studyViewFilter); + } + + List filteredSampleIdentifiers = studyViewFilterApplier.apply(studyViewFilter); + + if (filteredSampleIdentifiers.isEmpty()) { + return new ResponseEntity<>(new ArrayList<>(), HttpStatus.OK); + } + + List studyIds = new ArrayList<>(); + List sampleIds = new ArrayList<>(); + studyViewFilterUtil.extractStudyAndSampleIds(filteredSampleIdentifiers, studyIds, sampleIds); + + List result; + + result = projection == Projection.SUMMARY ? + studyViewService.getMutationCountsByGeneSpecific( + studyIds, + sampleIds, + gdFilters.stream().map(gdFilter -> new Pair<>(gdFilter.getHugoGeneSymbol(), gdFilter.getProfileType())).toList(), + studyViewFilter.getAlterationFilter() + ) : + studyViewService.getMutationTypeCountsByGeneSpecific( + studyIds, + sampleIds, + gdFilters.stream().map(gdFilter -> new Pair<>(gdFilter.getHugoGeneSymbol(), gdFilter.getProfileType())).toList() + ); + + return new ResponseEntity<>(result, HttpStatus.OK); + } } diff --git a/src/main/java/org/cbioportal/web/TreatmentController.java b/src/main/java/org/cbioportal/web/TreatmentController.java index c6da935de4c..370b7e9e99a 100644 --- a/src/main/java/org/cbioportal/web/TreatmentController.java +++ b/src/main/java/org/cbioportal/web/TreatmentController.java @@ -92,18 +92,18 @@ public ResponseEntity> getAllPatientTreatments( @RequestAttribute(required = false, value = "interceptedStudyViewFilter") StudyViewFilter interceptedStudyViewFilter ) { - boolean singleStudyUnfiltered = studyViewFilterUtil.isSingleStudyUnfiltered(interceptedStudyViewFilter); + boolean unfilteredQuery = studyViewFilterUtil.isUnfilteredQuery(interceptedStudyViewFilter); List treatments = - this.getInstance().cachableGetAllPatientTreatments(tier, interceptedStudyViewFilter, singleStudyUnfiltered); + this.getInstance().cachableGetAllPatientTreatments(tier, interceptedStudyViewFilter, unfilteredQuery); return new ResponseEntity<>(treatments, HttpStatus.OK); } @Cacheable( cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabled() && #singleStudyUnfiltered" + condition = "@cacheEnabledConfig.getEnabled() && #unfilteredQuery" ) public List cachableGetAllPatientTreatments( - ClinicalEventKeyCode tier, StudyViewFilter interceptedStudyViewFilter, boolean singleStudyUnfiltered + ClinicalEventKeyCode tier, StudyViewFilter interceptedStudyViewFilter, boolean unfilteredQuery ) { List sampleIdentifiers = studyViewFilterApplier.apply(interceptedStudyViewFilter); List sampleIds = new ArrayList<>(); @@ -139,18 +139,18 @@ public ResponseEntity> getAllSampleTreatments( @RequestAttribute(required = false, value = "interceptedStudyViewFilter") StudyViewFilter interceptedStudyViewFilter ) { - boolean singleStudyUnfiltered = studyViewFilterUtil.isSingleStudyUnfiltered(interceptedStudyViewFilter); + boolean unfilteredQuery = studyViewFilterUtil.isUnfilteredQuery(interceptedStudyViewFilter); List treatments = - this.getInstance().cacheableGetAllSampleTreatments(tier, interceptedStudyViewFilter, singleStudyUnfiltered); + this.getInstance().cacheableGetAllSampleTreatments(tier, interceptedStudyViewFilter, unfilteredQuery); return new ResponseEntity<>(treatments, HttpStatus.OK); } @Cacheable( cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabled() && #singleStudyUnfiltered" + condition = "@cacheEnabledConfig.getEnabled() && #unfilteredQuery" ) public List cacheableGetAllSampleTreatments( - ClinicalEventKeyCode tier, StudyViewFilter interceptedStudyViewFilter, boolean singleStudyUnfiltered + ClinicalEventKeyCode tier, StudyViewFilter interceptedStudyViewFilter, boolean unfilteredQuery ) { List sampleIdentifiers = studyViewFilterApplier.apply(interceptedStudyViewFilter); List sampleIds = new ArrayList<>(); diff --git a/src/main/java/org/cbioportal/web/config/WebServletContextListener.java b/src/main/java/org/cbioportal/web/config/WebServletContextListener.java index b05ec7b710f..8311df288df 100644 --- a/src/main/java/org/cbioportal/web/config/WebServletContextListener.java +++ b/src/main/java/org/cbioportal/web/config/WebServletContextListener.java @@ -30,7 +30,7 @@ public void contextDestroyed(ServletContextEvent arg0) { //Run this before web application is started @Override public void contextInitialized(ServletContextEvent arg0) { - this.properties = loadProperties(getResourceStream("portal.properties")); + this.properties = loadProperties(getResourceStream("application.properties")); this.showOncokb = Boolean.parseBoolean(getProperty("show.oncokb", "true")); this.oncokbToken = getProperty("oncokb.token", ""); diff --git a/src/main/java/org/cbioportal/web/parameter/MutationDataFilter.java b/src/main/java/org/cbioportal/web/parameter/MutationDataFilter.java new file mode 100644 index 00000000000..cb5401aaac6 --- /dev/null +++ b/src/main/java/org/cbioportal/web/parameter/MutationDataFilter.java @@ -0,0 +1,55 @@ +package org.cbioportal.web.parameter; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; + +import jakarta.validation.constraints.NotNull; + +import java.io.Serializable; +import java.util.List; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(NON_NULL) +public class MutationDataFilter implements Serializable { + private String hugoGeneSymbol; + private String profileType; + @NotNull + private MutationOption categorization; // filter by either having mutations or by mutation types + + private List> values; + + public String getHugoGeneSymbol() { + return hugoGeneSymbol; + } + + public void setHugoGeneSymbol(String hugoGeneSymbol) { + this.hugoGeneSymbol = hugoGeneSymbol; + } + + public String getProfileType() { + return profileType; + } + + public void setProfileType(String profileType) { + this.profileType = profileType; + } + + public MutationOption getCategorization() { + return categorization; + } + + public void setCategorization(MutationOption categorization) { + this.categorization = categorization; + } + + public List> getValues() { + return values; + } + + public void setValues(List> values) { + this.values = values; + } +} + diff --git a/src/main/java/org/cbioportal/web/parameter/MutationOption.java b/src/main/java/org/cbioportal/web/parameter/MutationOption.java new file mode 100644 index 00000000000..32d98555dce --- /dev/null +++ b/src/main/java/org/cbioportal/web/parameter/MutationOption.java @@ -0,0 +1,6 @@ +package org.cbioportal.web.parameter; + +public enum MutationOption { + MUTATED, // fetch mutation data with MUTATED, NOT_MUTATED, NOT_PROFILED in MutationFilterOption + MUTATION_TYPE // fetch mutation data with mutation types +} diff --git a/src/main/java/org/cbioportal/web/parameter/StudyViewFilter.java b/src/main/java/org/cbioportal/web/parameter/StudyViewFilter.java index b7354ed9b6c..738d3632a70 100644 --- a/src/main/java/org/cbioportal/web/parameter/StudyViewFilter.java +++ b/src/main/java/org/cbioportal/web/parameter/StudyViewFilter.java @@ -4,7 +4,6 @@ import java.util.List; import java.util.Objects; - import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -40,8 +39,8 @@ public class StudyViewFilter implements Serializable { private List> caseLists; private List customDataFilters; private AlterationFilter alterationFilter; - private List clinicalEventFilters; + private List mutationDataFilters; @AssertTrue private boolean isEitherSampleIdentifiersOrStudyIdsPresent() { @@ -225,4 +224,10 @@ public List getClinicalEventFilters() { public void setClinicalEventFilters(List clinicalEventFilters) { this.clinicalEventFilters = clinicalEventFilters; } + + public List getMutationDataFilters() { return mutationDataFilters; } + + public void setMutationDataFilters(List mutationDataFilters) { + this.mutationDataFilters = mutationDataFilters; + } } diff --git a/src/main/java/org/cbioportal/web/util/ClinicalDataEqualityFilterApplier.java b/src/main/java/org/cbioportal/web/util/ClinicalDataEqualityFilterApplier.java index 91ce735b31f..251b9f96e56 100644 --- a/src/main/java/org/cbioportal/web/util/ClinicalDataEqualityFilterApplier.java +++ b/src/main/java/org/cbioportal/web/util/ClinicalDataEqualityFilterApplier.java @@ -1,14 +1,16 @@ package org.cbioportal.web.util; -import java.util.List; - import org.apache.commons.collections4.map.MultiKeyMap; +import org.cbioportal.model.ClinicalData; import org.cbioportal.service.ClinicalDataService; import org.cbioportal.service.PatientService; import org.cbioportal.web.parameter.ClinicalDataFilter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.ArrayList; +import java.util.List; + @Component public class ClinicalDataEqualityFilterApplier extends ClinicalDataFilterApplier { @Autowired @@ -26,8 +28,23 @@ public Integer apply(List attributes, MultiKeyMap clinicalDataMap, String entityId, String studyId, - Boolean negateFilters + boolean negateFilters ) { return studyViewFilterUtil.getFilteredCountByDataEquality(attributes, clinicalDataMap, entityId, studyId, negateFilters); } + + public static MultiKeyMap> buildClinicalDataMap(List clinicalDatas) { + MultiKeyMap> clinicalDataMap = new MultiKeyMap<>(); + + clinicalDatas.forEach(clinicalData -> { + if (!clinicalDataMap.containsKey(clinicalData.getStudyId(), clinicalData.getSampleId(), clinicalData.getAttrId())) { + clinicalDataMap.put(clinicalData.getStudyId(), clinicalData.getSampleId(), clinicalData.getAttrId(), new ArrayList<>()); + } + clinicalDataMap + .get(clinicalData.getStudyId(), clinicalData.getSampleId(), clinicalData.getAttrId()) + .add(clinicalData.getAttrValue()); + }); + + return clinicalDataMap; + } } diff --git a/src/main/java/org/cbioportal/web/util/ClinicalDataFilterApplier.java b/src/main/java/org/cbioportal/web/util/ClinicalDataFilterApplier.java index 8e062c2ff33..5a46baca9c2 100644 --- a/src/main/java/org/cbioportal/web/util/ClinicalDataFilterApplier.java +++ b/src/main/java/org/cbioportal/web/util/ClinicalDataFilterApplier.java @@ -32,7 +32,7 @@ public ClinicalDataFilterApplier( public List apply( List sampleIdentifiers, List clinicalDataFilters, - Boolean negateFilters + boolean negateFilters ) { if (!clinicalDataFilters.isEmpty() && !sampleIdentifiers.isEmpty()) { List studyIds = new ArrayList<>(); @@ -86,5 +86,5 @@ public List apply( } // Must be overridden by child classes - protected abstract Integer apply(List attributes, MultiKeyMap clinicalDataMap, String entityId, String studyId, Boolean negateFilters); + protected abstract Integer apply(List attributes, MultiKeyMap clinicalDataMap, String entityId, String studyId, boolean negateFilters); } diff --git a/src/main/java/org/cbioportal/web/util/ClinicalDataIntervalFilterApplier.java b/src/main/java/org/cbioportal/web/util/ClinicalDataIntervalFilterApplier.java index e098929c6be..0484f024bc7 100644 --- a/src/main/java/org/cbioportal/web/util/ClinicalDataIntervalFilterApplier.java +++ b/src/main/java/org/cbioportal/web/util/ClinicalDataIntervalFilterApplier.java @@ -1,11 +1,8 @@ package org.cbioportal.web.util; -import java.math.BigDecimal; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - +import com.google.common.collect.Range; import org.apache.commons.collections4.map.MultiKeyMap; +import org.cbioportal.model.ClinicalData; import org.cbioportal.service.ClinicalDataService; import org.cbioportal.service.PatientService; import org.cbioportal.web.parameter.ClinicalDataFilter; @@ -13,7 +10,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.google.common.collect.Range; +import java.math.BigDecimal; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; @Component public class ClinicalDataIntervalFilterApplier extends ClinicalDataFilterApplier { @@ -33,7 +33,7 @@ public Integer apply(List attributes, MultiKeyMap clinicalDataMap, String entityId, String studyId, - Boolean negateFilters) { + boolean negateFilters) { int count = 0; for (ClinicalDataFilter filter : attributes) { @@ -133,4 +133,15 @@ private Boolean containsNA(ClinicalDataFilter filter) { return filter.getValues().stream().anyMatch( r -> r.getValue() != null && r.getValue().toUpperCase().equals("NA")); } + + public static MultiKeyMap buildClinicalDataMap(List clinicalDatas) { + MultiKeyMap clinicalDataMap = new MultiKeyMap<>(); + + clinicalDatas.forEach(clinicalData -> + clinicalDataMap.put(clinicalData.getStudyId(), clinicalData.getSampleId(), clinicalData.getAttrId(), + clinicalData.getAttrValue()) + ); + + return clinicalDataMap; + } } diff --git a/src/main/java/org/cbioportal/web/util/CustomDataFilterApplier.java b/src/main/java/org/cbioportal/web/util/CustomDataFilterApplier.java index bf4985f15fb..ed37c9a13a4 100644 --- a/src/main/java/org/cbioportal/web/util/CustomDataFilterApplier.java +++ b/src/main/java/org/cbioportal/web/util/CustomDataFilterApplier.java @@ -1,8 +1,5 @@ package org.cbioportal.web.util; -import static org.cbioportal.utils.removeme.Session.*; - - import org.apache.commons.collections4.map.MultiKeyMap; import org.cbioportal.service.CustomDataService; import org.cbioportal.service.util.CustomDataSession; @@ -40,7 +37,7 @@ public CustomDataFilterApplier( public List apply( List sampleIdentifiers, List dataFilters, - Boolean negateFilters + boolean negateFilters ) { if (dataFilters.isEmpty() || sampleIdentifiers.isEmpty()) { return sampleIdentifiers; @@ -91,7 +88,7 @@ public List apply( private List filterCustomData( List customDataFilters, - Boolean negateFilters, + boolean negateFilters, List sampleIdentifiers, Map customDataSessionById, MultiKeyMap clinicalDataMap diff --git a/src/main/java/org/cbioportal/web/util/DataFilterApplier.java b/src/main/java/org/cbioportal/web/util/DataFilterApplier.java index 172931160a3..ad5d6521658 100644 --- a/src/main/java/org/cbioportal/web/util/DataFilterApplier.java +++ b/src/main/java/org/cbioportal/web/util/DataFilterApplier.java @@ -10,6 +10,6 @@ public interface DataFilterApplier { List apply( List sampleIdentifiers, List dataFilters, - Boolean negateFilters + boolean negateFilters ); } diff --git a/src/main/java/org/cbioportal/web/util/InvolvedCancerStudyExtractorInterceptor.java b/src/main/java/org/cbioportal/web/util/InvolvedCancerStudyExtractorInterceptor.java index 7e500845fb1..314627baf2e 100644 --- a/src/main/java/org/cbioportal/web/util/InvolvedCancerStudyExtractorInterceptor.java +++ b/src/main/java/org/cbioportal/web/util/InvolvedCancerStudyExtractorInterceptor.java @@ -33,15 +33,6 @@ package org.cbioportal.web.util; import com.fasterxml.jackson.databind.ObjectMapper; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.cbioportal.model.AlterationFilter; @@ -76,9 +67,16 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.web.servlet.HandlerInterceptor; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + public class InvolvedCancerStudyExtractorInterceptor implements HandlerInterceptor { @Autowired @@ -86,7 +84,6 @@ public class InvolvedCancerStudyExtractorInterceptor implements HandlerIntercept private ObjectMapper objectMapper = new ObjectMapper(); - @Qualifier("staticRefCacheMapUtil") @Autowired private CacheMapUtil cacheMapUtil; @@ -104,6 +101,7 @@ public class InvolvedCancerStudyExtractorInterceptor implements HandlerIntercept public static final String STUDY_VIEW_CUSTOM_DATA_BIN_COUNTS_PATH = "/custom-data-bin-counts/fetch"; public static final String STUDY_VIEW_GENOMICL_DATA_BIN_COUNTS_PATH = "/genomic-data-bin-counts/fetch"; public static final String STUDY_VIEW_GENOMICL_DATA_COUNTS_PATH = "/genomic-data-counts/fetch"; + public static final String STUDY_VIEW_MUTATION_DATA_COUNTS_PATH = "/mutation-data-counts/fetch"; public static final String STUDY_VIEW_GENERIC_ASSAY_DATA_BIN_COUNTS_PATH = "/generic-assay-data-bin-counts/fetch"; public static final String STUDY_VIEW_GENERIC_ASSAY_DATA_COUNTS_PATH = "/generic-assay-data-counts/fetch"; public static final String STUDY_VIEW_CLINICAL_DATA_COUNTS_PATH = "/clinical-data-counts/fetch"; @@ -164,7 +162,7 @@ public class InvolvedCancerStudyExtractorInterceptor implements HandlerIntercept return extractAttributesFromClinicalDataBinCountFilter(request); } else if (requestPathInfo.equals(STUDY_VIEW_GENOMICL_DATA_BIN_COUNTS_PATH)) { return extractAttributesFromGenomicDataBinCountFilter(request); - } else if (requestPathInfo.equals(STUDY_VIEW_GENOMICL_DATA_COUNTS_PATH)) { + } else if (Arrays.asList(STUDY_VIEW_GENOMICL_DATA_COUNTS_PATH, STUDY_VIEW_MUTATION_DATA_COUNTS_PATH).contains(requestPathInfo)) { return extractAttributesFromGenomicDataCountFilter(request); } else if (requestPathInfo.equals(STUDY_VIEW_GENERIC_ASSAY_DATA_BIN_COUNTS_PATH)) { return extractAttributesFromGenericAssayDataBinCountFilter(request); diff --git a/src/main/java/org/cbioportal/web/util/StudyViewFilterApplier.java b/src/main/java/org/cbioportal/web/util/StudyViewFilterApplier.java index de4e5440e10..1684902a437 100644 --- a/src/main/java/org/cbioportal/web/util/StudyViewFilterApplier.java +++ b/src/main/java/org/cbioportal/web/util/StudyViewFilterApplier.java @@ -1,36 +1,92 @@ package org.cbioportal.web.util; -import java.util.*; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.map.MultiKeyMap; -import org.cbioportal.model.*; +import org.cbioportal.model.Binnable; +import org.cbioportal.model.ClinicalAttribute; +import org.cbioportal.model.ClinicalData; +import org.cbioportal.model.DataBin; +import org.cbioportal.model.DiscreteCopyNumberData; +import org.cbioportal.model.Gene; import org.cbioportal.model.GeneFilter; +import org.cbioportal.model.GeneFilterQuery; +import org.cbioportal.model.GenePanel; +import org.cbioportal.model.GenePanelData; +import org.cbioportal.model.GenePanelToGene; +import org.cbioportal.model.GenericAssayDataBin; +import org.cbioportal.model.GenomicDataBin; +import org.cbioportal.model.MolecularData; +import org.cbioportal.model.MolecularProfile; import org.cbioportal.model.MolecularProfile.MolecularAlterationType; -import org.cbioportal.service.*; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.model.Mutation; +import org.cbioportal.model.MutationFilterOption; +import org.cbioportal.model.Sample; +import org.cbioportal.model.SampleList; +import org.cbioportal.model.UniqueKeyBase; +import org.cbioportal.service.ClinicalAttributeService; +import org.cbioportal.service.DiscreteCopyNumberService; +import org.cbioportal.service.GenePanelService; +import org.cbioportal.service.GeneService; +import org.cbioportal.service.GenericAssayService; +import org.cbioportal.service.MolecularDataService; +import org.cbioportal.service.MolecularProfileService; +import org.cbioportal.service.MutationService; +import org.cbioportal.service.SampleListService; +import org.cbioportal.service.SampleService; +import org.cbioportal.service.StructuralVariantService; import org.cbioportal.service.exception.MolecularProfileNotFoundException; import org.cbioportal.service.util.MolecularProfileUtil; -import org.cbioportal.web.parameter.*; -import org.cbioportal.web.util.appliers.*; +import org.cbioportal.web.parameter.ClinicalDataFilter; +import org.cbioportal.web.parameter.ClinicalDataType; +import org.cbioportal.web.parameter.DataBinCountFilter; +import org.cbioportal.web.parameter.DataBinFilter; +import org.cbioportal.web.parameter.DataBinMethod; +import org.cbioportal.web.parameter.DataFilter; +import org.cbioportal.web.parameter.DataFilterValue; +import org.cbioportal.web.parameter.DiscreteCopyNumberEventType; +import org.cbioportal.web.parameter.GeneIdType; +import org.cbioportal.web.parameter.GenericAssayDataBinCountFilter; +import org.cbioportal.web.parameter.GenericAssayDataBinFilter; +import org.cbioportal.web.parameter.GenericAssayDataFilter; +import org.cbioportal.web.parameter.GenomicDataBinCountFilter; +import org.cbioportal.web.parameter.GenomicDataBinFilter; +import org.cbioportal.web.parameter.GenomicDataFilter; +import org.cbioportal.web.parameter.MutationDataFilter; +import org.cbioportal.web.parameter.MutationOption; +import org.cbioportal.web.parameter.Projection; +import org.cbioportal.web.parameter.SampleIdentifier; +import org.cbioportal.web.parameter.StudyViewFilter; +import org.cbioportal.web.util.appliers.StudyViewSubFilterApplier; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; @Component public class StudyViewFilterApplier { @Autowired private ApplicationContext applicationContext; - + + private StudyViewFilterApplier instance; + // This gets initialized and overwritten. We do this because Spring's unit tests // don't know how to autowire this, even though production Spring does. If we // don't give this an initial value, we get NPEs. @Autowired - private List subFilterAppliers = new ArrayList<>(); - + private final List subFilterAppliers = new ArrayList<>(); @Autowired private SampleService sampleService; @@ -67,18 +123,23 @@ public class StudyViewFilterApplier { @Autowired private MolecularProfileUtil molecularProfileUtil; + + private StudyViewFilterApplier getInstance() { + if (Objects.isNull(instance)) { + instance = applicationContext.getBean(StudyViewFilterApplier.class); + } + return instance; + } + Function sampleToSampleIdentifier = new Function() { public SampleIdentifier apply(Sample sample) { - SampleIdentifier sampleIdentifier = new SampleIdentifier(); - sampleIdentifier.setSampleId(sample.getStableId()); - sampleIdentifier.setStudyId(sample.getCancerStudyIdentifier()); - return sampleIdentifier; + return studyViewFilterUtil.buildSampleIdentifier(sample.getCancerStudyIdentifier(), sample.getStableId()); } }; public List apply(StudyViewFilter studyViewFilter) { - return this.cachedApply(studyViewFilter); + return this.getInstance().cachedApply(studyViewFilter); } @Cacheable( @@ -89,7 +150,7 @@ public List cachedApply(StudyViewFilter studyViewFilter) { return this.apply(studyViewFilter, false); } - public List apply(StudyViewFilter studyViewFilter, Boolean negateFilters) { + public List apply(StudyViewFilter studyViewFilter, boolean negateFilters) { List sampleIdentifiers = new ArrayList<>(); if (studyViewFilter == null) { @@ -108,7 +169,7 @@ public List apply(StudyViewFilter studyViewFilter, Boolean neg } List studyIds = sampleIdentifiers.stream().map(SampleIdentifier::getStudyId).distinct() - .collect(Collectors.toList()); + .collect(Collectors.toList()); List clinicalDataEqualityFilters = new ArrayList<>(); List clinicalDataIntervalFilters = new ArrayList<>(); @@ -117,14 +178,14 @@ public List apply(StudyViewFilter studyViewFilter, Boolean neg if (!CollectionUtils.isEmpty(clinicalDataFilters)) { List attributeIds = clinicalDataFilters.stream().map(ClinicalDataFilter::getAttributeId) - .collect(Collectors.toList()); + .collect(Collectors.toList()); List clinicalAttributes = clinicalAttributeService - .getClinicalAttributesByStudyIdsAndAttributeIds(studyIds, attributeIds); + .getClinicalAttributesByStudyIdsAndAttributeIds(studyIds, attributeIds); Map clinicalAttributeMap = clinicalAttributes.stream() - .collect(Collectors.toMap(ClinicalAttribute::getAttrId, Function.identity(), (a, b) -> { - return a.getDatatype().equals("STRING") ? a : b; - })); + .collect(Collectors.toMap(ClinicalAttribute::getAttrId, Function.identity(), (a, b) -> { + return a.getDatatype().equals("STRING") ? a : b; + })); clinicalDataFilters.forEach(clinicalDataFilter -> { String attributeId = clinicalDataFilter.getAttributeId(); @@ -148,14 +209,15 @@ public List apply(StudyViewFilter studyViewFilter, Boolean neg if (!CollectionUtils.isEmpty(studyViewFilter.getCustomDataFilters())) { sampleIdentifiers = customDataFilterApplier.apply(sampleIdentifiers, studyViewFilter.getCustomDataFilters(), - negateFilters); + negateFilters); } List molecularProfiles = null; if (!CollectionUtils.isEmpty(studyViewFilter.getGeneFilters()) - || !CollectionUtils.isEmpty(studyViewFilter.getGenomicDataFilters()) - || !CollectionUtils.isEmpty(studyViewFilter.getGenericAssayDataFilters()) - || !CollectionUtils.isEmpty(studyViewFilter.getGenomicProfiles())) { + || !CollectionUtils.isEmpty(studyViewFilter.getMutationDataFilters()) + || !CollectionUtils.isEmpty(studyViewFilter.getGenomicDataFilters()) + || !CollectionUtils.isEmpty(studyViewFilter.getGenericAssayDataFilters()) + || !CollectionUtils.isEmpty(studyViewFilter.getGenomicProfiles())) { molecularProfiles = molecularProfileService.getMolecularProfilesInStudies(studyIds, "SUMMARY"); } @@ -183,38 +245,38 @@ public List apply(StudyViewFilter studyViewFilter, Boolean neg } }); } - + if (!CollectionUtils.isEmpty(genomicDataEqualityFilters)) { sampleIdentifiers = equalityFilterExpressionData(sampleIdentifiers, molecularProfiles, genomicDataEqualityFilters, negateFilters); } - + if (!CollectionUtils.isEmpty(genomicDataIntervalFilters)) { sampleIdentifiers = intervalFilterExpressionData(sampleIdentifiers, molecularProfiles, genomicDataIntervalFilters, negateFilters); } sampleIdentifiers = intervalFilterExpressionData(sampleIdentifiers, molecularProfiles, - studyViewFilter.getGenericAssayDataFilters(), negateFilters); + studyViewFilter.getGenericAssayDataFilters(), negateFilters); if (!CollectionUtils.isEmpty(studyViewFilter.getGeneFilters())) { Map molecularProfileMap = molecularProfiles.stream() - .collect(Collectors.toMap(MolecularProfile::getStableId, Function.identity())); + .collect(Collectors.toMap(MolecularProfile::getStableId, Function.identity())); List mutatedGeneFilters = new ArrayList(); List structuralVariantGeneFilters = new ArrayList(); List cnaGeneFilters = new ArrayList(); splitGeneFiltersByMolecularAlterationType(studyViewFilter.getGeneFilters(), molecularProfileMap, - mutatedGeneFilters, structuralVariantGeneFilters, cnaGeneFilters); + mutatedGeneFilters, structuralVariantGeneFilters, cnaGeneFilters); if ((mutatedGeneFilters.size() + structuralVariantGeneFilters.size() + cnaGeneFilters.size()) == studyViewFilter - .getGeneFilters().size()) { + .getGeneFilters().size()) { if (!mutatedGeneFilters.isEmpty()) { sampleIdentifiers = filterMutatedGenes(mutatedGeneFilters, molecularProfileMap, sampleIdentifiers); } if (!structuralVariantGeneFilters.isEmpty()) { sampleIdentifiers = filterStructuralVariantGenes(structuralVariantGeneFilters, molecularProfileMap, - sampleIdentifiers); + sampleIdentifiers); } if (!cnaGeneFilters.isEmpty()) { sampleIdentifiers = filterCNAGenes(cnaGeneFilters, molecularProfileMap, sampleIdentifiers); @@ -227,10 +289,10 @@ public List apply(StudyViewFilter studyViewFilter, Boolean neg if (!CollectionUtils.isEmpty(studyViewFilter.getGenomicProfiles())) { Map> groupStudySampleIdentifiers = sampleIdentifiers.stream() - .collect(Collectors.groupingBy(SampleIdentifier::getStudyId)); + .collect(Collectors.groupingBy(SampleIdentifier::getStudyId)); Map> molecularProfileSet = molecularProfileUtil - .categorizeMolecularProfilesByStableIdSuffixes(molecularProfiles); + .categorizeMolecularProfilesByStableIdSuffixes(molecularProfiles); List molecularProfileSampleIdentifiers = new ArrayList<>(); @@ -238,31 +300,30 @@ public List apply(StudyViewFilter studyViewFilter, Boolean neg profileValues.stream().forEach(profileValue -> { molecularProfileSet.getOrDefault(profileValue, new ArrayList<>()).stream().forEach(profile -> { groupStudySampleIdentifiers.getOrDefault(profile.getCancerStudyIdentifier(), new ArrayList<>()) - .forEach(sampleIdentifier -> { - MolecularProfileCaseIdentifier profileCaseIdentifier = new MolecularProfileCaseIdentifier(); - profileCaseIdentifier.setMolecularProfileId(profile.getStableId()); - profileCaseIdentifier.setCaseId(sampleIdentifier.getSampleId()); - molecularProfileSampleIdentifiers.add(profileCaseIdentifier); - }); + .forEach(sampleIdentifier -> { + MolecularProfileCaseIdentifier profileCaseIdentifier = new MolecularProfileCaseIdentifier(); + profileCaseIdentifier.setMolecularProfileId(profile.getStableId()); + profileCaseIdentifier.setCaseId(sampleIdentifier.getSampleId()); + molecularProfileSampleIdentifiers.add(profileCaseIdentifier); + }); }); }); }); List genePanelData = genePanelService - .fetchGenePanelDataInMultipleMolecularProfiles(molecularProfileSampleIdentifiers); + .fetchGenePanelDataInMultipleMolecularProfiles(molecularProfileSampleIdentifiers); for (List profileValues : studyViewFilter.getGenomicProfiles()) { Map profileMap = profileValues.stream().flatMap( profileValue -> molecularProfileSet.getOrDefault(profileValue, new ArrayList<>()).stream()) - .collect(Collectors.toMap(MolecularProfile::getStableId, Function.identity())); + .collect(Collectors.toMap(MolecularProfile::getStableId, Function.identity())); Set filteredSampleIdentifiers = new HashSet<>(); genePanelData.forEach(datum -> { if (datum.getProfiled() && profileMap.containsKey(datum.getMolecularProfileId())) { - SampleIdentifier sampleIdentifier = new SampleIdentifier(); - sampleIdentifier.setStudyId(datum.getStudyId()); - sampleIdentifier.setSampleId(datum.getSampleId()); + SampleIdentifier sampleIdentifier = + studyViewFilterUtil.buildSampleIdentifier(datum.getStudyId(), datum.getSampleId()); filteredSampleIdentifiers.add(sampleIdentifier); } }); @@ -272,54 +333,77 @@ public List apply(StudyViewFilter studyViewFilter, Boolean neg if (!CollectionUtils.isEmpty(studyViewFilter.getCaseLists())) { List sampleLists = sampleListService.getAllSampleListsInStudies(studyIds, - Projection.DETAILED.name()); + Projection.DETAILED.name()); Map> groupedSampleListByListType = studyViewFilterUtil - .categorizeSampleLists(sampleLists); + .categorizeSampleLists(sampleLists); for (List sampleListTypes : studyViewFilter.getCaseLists()) { List filteredSampleIdentifiers = sampleListTypes.stream() - .flatMap(sampleListType -> groupedSampleListByListType - .getOrDefault(sampleListType, new ArrayList<>()).stream().flatMap(sampleList -> { - return sampleList.getSampleIds().stream().map(sampleId -> { - SampleIdentifier sampleIdentifier = new SampleIdentifier(); - sampleIdentifier.setStudyId(sampleList.getCancerStudyIdentifier()); - sampleIdentifier.setSampleId(sampleId); - return sampleIdentifier; - }); - })) - .collect(Collectors.toList()); + .flatMap(sampleListType -> groupedSampleListByListType + .getOrDefault(sampleListType, new ArrayList<>()).stream().flatMap(sampleList -> { + return sampleList.getSampleIds().stream().map(sampleId -> + studyViewFilterUtil.buildSampleIdentifier( + sampleList.getCancerStudyIdentifier(), + sampleId)); + })) + .toList(); sampleIdentifiers.retainAll(filteredSampleIdentifiers); } } + List mutationOptionDataFilters = new ArrayList<>(); + List mutationTypeDataFilters = new ArrayList<>(); + + List mutationDataFilters = studyViewFilter.getMutationDataFilters(); + + if (!CollectionUtils.isEmpty(mutationDataFilters)) { + mutationDataFilters.forEach(mutationDataFilter -> { + if (mutationDataFilter.getCategorization() == MutationOption.MUTATED) { + mutationOptionDataFilters.add(mutationDataFilter); + } else { + mutationTypeDataFilters.add(mutationDataFilter); + } + }); + } + + if (!CollectionUtils.isEmpty(mutationOptionDataFilters)) { + sampleIdentifiers = filterMutationData(sampleIdentifiers, molecularProfiles, + mutationOptionDataFilters, negateFilters, clinicalDataEqualityFilterApplier); + } + + if (!CollectionUtils.isEmpty(mutationTypeDataFilters)) { + sampleIdentifiers = filterMutationData(sampleIdentifiers, molecularProfiles, + mutationTypeDataFilters, negateFilters, clinicalDataEqualityFilterApplier); + } + return chainSubFilters(studyViewFilter, sampleIdentifiers); } - + private List chainSubFilters(StudyViewFilter studyViewFilter, List sampleIdentifiers) { for (StudyViewSubFilterApplier subFilterApplier : subFilterAppliers) { if (!sampleIdentifiers.isEmpty() && subFilterApplier.shouldApplyFilter(studyViewFilter)) { sampleIdentifiers = subFilterApplier.filter(sampleIdentifiers, studyViewFilter); } } - + return sampleIdentifiers; } private List intervalFilterClinicalData(List sampleIdentifiers, List clinicalDataIntervalFilters, - Boolean negateFilters) { + boolean negateFilters) { return clinicalDataIntervalFilterApplier.apply(sampleIdentifiers, clinicalDataIntervalFilters, negateFilters); } private List equalityFilterClinicalData(List sampleIdentifiers, List clinicalDataEqualityFilters, - Boolean negateFilters) { + boolean negateFilters) { return clinicalDataEqualityFilterApplier.apply(sampleIdentifiers, clinicalDataEqualityFilters, negateFilters); } private List filterMutatedGenes(List mutatedGenefilters, - Map molecularProfileMap, List sampleIdentifiers) { + Map molecularProfileMap, List sampleIdentifiers) { if (sampleIdentifiers == null || sampleIdentifiers.isEmpty()) { return new ArrayList<>(); @@ -328,23 +412,23 @@ private List filterMutatedGenes(List mutatedGenefi for (GeneFilter genefilter : mutatedGenefilters) { List filteredMolecularProfiles = genefilter - .getMolecularProfileIds() - .stream() - .map(molecularProfileId -> molecularProfileMap.get(molecularProfileId)) - .collect(Collectors.toList()); + .getMolecularProfileIds() + .stream() + .map(molecularProfileMap::get) + .toList(); Map> mapByStudyId = filteredMolecularProfiles - .stream() - .collect(Collectors.groupingBy(MolecularProfile::getCancerStudyIdentifier)); + .stream() + .collect(Collectors.groupingBy(MolecularProfile::getCancerStudyIdentifier)); for (List geneQueries : genefilter.getGeneQueries()) { List studyIds = new ArrayList<>(); List sampleIds = new ArrayList<>(); List hugoGeneSymbols = geneQueries - .stream() - .map(GeneFilterQuery::getHugoGeneSymbol) - .collect(Collectors.toList()); + .stream() + .map(GeneFilterQuery::getHugoGeneSymbol) + .toList(); Map symbolToEntrezGeneId = geneService .fetchGenes(new ArrayList<>(hugoGeneSymbols), @@ -374,17 +458,12 @@ private List filterMutatedGenes(List mutatedGenefi } sampleIdentifiers = mutationService - .getMutationsInMultipleMolecularProfilesByGeneQueries(molecularProfileIds, sampleIds, geneQueries, - Projection.ID.name(), null, null, null, null) - .stream() - .map(m -> { - SampleIdentifier sampleIdentifier = new SampleIdentifier(); - sampleIdentifier.setSampleId(m.getSampleId()); - sampleIdentifier.setStudyId(m.getStudyId()); - return sampleIdentifier; - }) - .distinct() - .collect(Collectors.toList()); + .getMutationsInMultipleMolecularProfilesByGeneQueries(molecularProfileIds, sampleIds, geneQueries, + Projection.ID.name(), null, null, null, null) + .stream() + .map(m -> studyViewFilterUtil.buildSampleIdentifier(m.getStudyId(), m.getSampleId())) + .distinct() + .collect(Collectors.toList()); } } @@ -392,8 +471,8 @@ private List filterMutatedGenes(List mutatedGenefi } private List filterStructuralVariantGenes(List svGenefilters, - Map molecularProfileMap, List sampleIdentifiers) { - + Map molecularProfileMap, List sampleIdentifiers) { + if (sampleIdentifiers == null || sampleIdentifiers.isEmpty()) { return new ArrayList<>(); } @@ -401,14 +480,14 @@ private List filterStructuralVariantGenes(List svG for (GeneFilter genefilter : svGenefilters) { List filteredMolecularProfiles = genefilter - .getMolecularProfileIds() - .stream() - .map(molecularProfileId -> molecularProfileMap.get(molecularProfileId)) - .collect(Collectors.toList()); + .getMolecularProfileIds() + .stream() + .map(molecularProfileMap::get) + .toList(); Map> mapByStudyId = filteredMolecularProfiles - .stream() - .collect(Collectors.groupingBy(MolecularProfile::getCancerStudyIdentifier)); + .stream() + .collect(Collectors.groupingBy(MolecularProfile::getCancerStudyIdentifier)); for (List geneQueries : genefilter.getGeneQueries()) { List studyIds = new ArrayList<>(); @@ -417,7 +496,7 @@ private List filterStructuralVariantGenes(List svG List hugoGeneSymbols = geneQueries .stream() .map(GeneFilterQuery::getHugoGeneSymbol) - .collect(Collectors.toList()); + .toList(); Map symbolToEntrezGeneId = geneService .fetchGenes(new ArrayList<>(hugoGeneSymbols), @@ -448,16 +527,11 @@ private List filterStructuralVariantGenes(List svG } sampleIdentifiers = structuralVariantService - .fetchStructuralVariantsByGeneQueries(molecularProfileIds, sampleIds, geneQueries) - .stream() - .map(m -> { - SampleIdentifier sampleIdentifier = new SampleIdentifier(); - sampleIdentifier.setSampleId(m.getSampleId()); - sampleIdentifier.setStudyId(m.getStudyId()); - return sampleIdentifier; - }) - .distinct() - .collect(Collectors.toList()); + .fetchStructuralVariantsByGeneQueries(molecularProfileIds, sampleIds, geneQueries) + .stream() + .map(m -> studyViewFilterUtil.buildSampleIdentifier(m.getStudyId(), m.getSampleId())) + .distinct() + .collect(Collectors.toList()); } } @@ -465,8 +539,8 @@ private List filterStructuralVariantGenes(List svG } private List filterCNAGenes(List cnaGeneFilters, - Map molecularProfileMap, List sampleIdentifiers) { - + Map molecularProfileMap, List sampleIdentifiers) { + if (sampleIdentifiers == null || sampleIdentifiers.isEmpty()) { return new ArrayList<>(); } @@ -474,8 +548,8 @@ private List filterCNAGenes(List cnaGeneFilters, for (GeneFilter geneFilter : cnaGeneFilters) { List filteredMolecularProfiles = geneFilter.getMolecularProfileIds().stream() - .map(molecularProfileId -> molecularProfileMap.get(molecularProfileId)) - .collect(Collectors.toList()); + .map(molecularProfileMap::get) + .toList(); for (List geneQueries : geneFilter.getGeneQueries()) { @@ -485,7 +559,7 @@ private List filterCNAGenes(List cnaGeneFilters, List molecularProfileIds = new ArrayList<>(); Map> mapByStudyId = filteredMolecularProfiles.stream() - .collect(Collectors.groupingBy(MolecularProfile::getCancerStudyIdentifier)); + .collect(Collectors.groupingBy(MolecularProfile::getCancerStudyIdentifier)); int removedSampleCount = 0; for (int i = 0; i < studyIds.size(); i++) { String studyId = studyIds.get(i); @@ -498,78 +572,120 @@ private List filterCNAGenes(List cnaGeneFilters, } List resultList = DiscreteCopyNumberEventType.ALL - .getAlterationTypes().stream().flatMap(alterationType -> { - - List filteredGeneQueries = geneQueries.stream() - .filter(geneQuery -> geneQuery.getAlterations().stream() - .filter(alteration -> alteration.getCode() == alterationType) - .count() > 0) - .collect(Collectors.toList()); - - List hugoGeneSymbols = filteredGeneQueries.stream() - .map(GeneFilterQuery::getHugoGeneSymbol).collect(Collectors.toList()); - - Map symbolToEntrezGeneId = geneService - .fetchGenes(new ArrayList<>(hugoGeneSymbols), - GeneIdType.HUGO_GENE_SYMBOL.name(), Projection.SUMMARY.name()) - .stream().collect(Collectors.toMap(x -> x.getHugoGeneSymbol(), x -> x.getEntrezGeneId())); - - filteredGeneQueries.removeIf( - q -> !symbolToEntrezGeneId.containsKey(q.getHugoGeneSymbol()) - ); - - filteredGeneQueries.stream().forEach( - q -> q.setEntrezGeneId(symbolToEntrezGeneId.get(q.getHugoGeneSymbol())) - ); - - List copyNumberDatas = new ArrayList<>(); - if (!filteredGeneQueries.isEmpty()) { - copyNumberDatas = discreteCopyNumberService - .getDiscreteCopyNumbersInMultipleMolecularProfilesByGeneQueries( - molecularProfileIds, - sampleIds, - filteredGeneQueries, - Projection.ID.name()); - } - return copyNumberDatas.stream(); - }).collect(Collectors.toList()); - - sampleIdentifiers = resultList.stream().map(d -> { - SampleIdentifier sampleIdentifier = new SampleIdentifier(); - sampleIdentifier.setSampleId(d.getSampleId()); - sampleIdentifier.setStudyId(d.getStudyId()); - return sampleIdentifier; - }).distinct().collect(Collectors.toList()); + .getAlterationTypes().stream().flatMap(alterationType -> { + + List filteredGeneQueries = geneQueries.stream() + .filter(geneQuery -> geneQuery.getAlterations().stream().anyMatch(alteration -> alteration.getCode() == alterationType)) + .collect(Collectors.toList()); + + List hugoGeneSymbols = filteredGeneQueries.stream() + .map(GeneFilterQuery::getHugoGeneSymbol).toList(); + + Map symbolToEntrezGeneId = geneService + .fetchGenes(new ArrayList<>(hugoGeneSymbols), + GeneIdType.HUGO_GENE_SYMBOL.name(), Projection.SUMMARY.name()) + .stream().collect(Collectors.toMap(Gene::getHugoGeneSymbol, Gene::getEntrezGeneId)); + + filteredGeneQueries.removeIf( + q -> !symbolToEntrezGeneId.containsKey(q.getHugoGeneSymbol()) + ); + + filteredGeneQueries.forEach( + q -> q.setEntrezGeneId(symbolToEntrezGeneId.get(q.getHugoGeneSymbol())) + ); + + List copyNumberDatas = new ArrayList<>(); + if (!filteredGeneQueries.isEmpty()) { + copyNumberDatas = discreteCopyNumberService + .getDiscreteCopyNumbersInMultipleMolecularProfilesByGeneQueries( + molecularProfileIds, + sampleIds, + filteredGeneQueries, + Projection.ID.name()); + } + return copyNumberDatas.stream(); + }).toList(); + + sampleIdentifiers = resultList.stream().map( + d -> studyViewFilterUtil.buildSampleIdentifier(d.getStudyId(), d.getSampleId()) + ).distinct().collect(Collectors.toList()); } } return sampleIdentifiers; } + private List filterMutationData(List sampleIdentifiers, + List molecularProfiles, List mutationDataFilters, + boolean negateFilters, ClinicalDataFilterApplier clinicalDataFilterApplier) { + if (CollectionUtils.isNotEmpty(mutationDataFilters) && CollectionUtils.isNotEmpty(sampleIdentifiers)) { + List clinicalDatas = + fetchMutationDataAndTransformToClinicalDataList(sampleIdentifiers, molecularProfiles, mutationDataFilters); + + + MultiKeyMap clinicalDataMap; + if (clinicalDataFilterApplier instanceof ClinicalDataEqualityFilterApplier) { + clinicalDataMap = ClinicalDataEqualityFilterApplier.buildClinicalDataMap(clinicalDatas); + } else { + clinicalDataMap = ClinicalDataIntervalFilterApplier.buildClinicalDataMap(clinicalDatas); + } + + List newSampleIdentifiers = new ArrayList<>(); + + // loop through each mutationDataFilter and filter data + for (MutationDataFilter mutationDataFilter : mutationDataFilters) { + // loop through each list of DataFilterValue and do union or intersection selections + for (List values : mutationDataFilter.getValues()) { + ClinicalDataFilter clinicalDataFilter = new ClinicalDataFilter(); + clinicalDataFilter.setAttributeId(mutationDataFilter.getHugoGeneSymbol() + mutationDataFilter.getProfileType()); + clinicalDataFilter.setValues(values); + + List attributes = Collections.singletonList(clinicalDataFilter); + + // union selection: filter all samples that have at least one value from a list of DataFilterValue, e.g. Missense_Mutation, In_Shift_Del, ... + List filteredSampleIdentifiers = filterSampleIdentifiers( + sampleIdentifiers, attributes, clinicalDataMap, clinicalDataFilterApplier, negateFilters + ); + + if (newSampleIdentifiers.isEmpty()) { + newSampleIdentifiers = filteredSampleIdentifiers; + } else { + // intersection selection: retain shared samples from each selection for all mutationDataFilter + newSampleIdentifiers.retainAll(filteredSampleIdentifiers); + } + } + } + + return newSampleIdentifiers.stream().distinct().toList(); + } + + return sampleIdentifiers; + } + private void splitGeneFiltersByMolecularAlterationType(List genefilters, - Map molecularProfileMap, List mutatedGeneFilters, - List structuralVariantGeneFilters, List cnaGeneFilters) { + Map molecularProfileMap, List mutatedGeneFilters, + List structuralVariantGeneFilters, List cnaGeneFilters) { for (GeneFilter genefilter : genefilters) { List filteredMolecularProfiles = genefilter.getMolecularProfileIds().stream() - // need this filter criteria since profile id might be present - // in filter but the study might already been filtered out - .filter(molecularProfileMap::containsKey) - .map(molecularProfileMap::get) - .collect(Collectors.toList()); + // need this filter criteria since profile id might be present + // in filter but the study might already been filtered out + .filter(molecularProfileMap::containsKey) + .map(molecularProfileMap::get) + .toList(); Set alterationTypes = filteredMolecularProfiles.stream() - .map(MolecularProfile::getMolecularAlterationType) - .collect(Collectors.toSet()); + .map(MolecularProfile::getMolecularAlterationType) + .collect(Collectors.toSet()); Set dataTypes = filteredMolecularProfiles.stream().map(MolecularProfile::getDatatype) - .collect(Collectors.toSet()); + .collect(Collectors.toSet()); Set filteredMolecularProfileIds = filteredMolecularProfiles - .stream() - .map(MolecularProfile::getStableId) - .collect(Collectors.toSet()); + .stream() + .map(MolecularProfile::getStableId) + .collect(Collectors.toSet()); genefilter.setMolecularProfileIds(filteredMolecularProfileIds); if (alterationTypes.size() == 1) { @@ -580,7 +696,7 @@ private void splitGeneFiltersByMolecularAlterationType(List genefilt } else if (alterationType == MolecularAlterationType.MUTATION_EXTENDED) { mutatedGeneFilters.add(genefilter); } else if (alterationType == MolecularAlterationType.COPY_NUMBER_ALTERATION - && dataTypes.size() == 1 && dataTypes.iterator().next().equals("DISCRETE")) { + && dataTypes.size() == 1 && dataTypes.iterator().next().equals("DISCRETE")) { cnaGeneFilters.add(genefilter); } } @@ -596,7 +712,7 @@ public List getUniqkeyKeys(List studyIds, List caseIds) } public List getDataBins( - DataBinMethod dataBinMethod, T dataBinCountFilter) { + DataBinMethod dataBinMethod, T dataBinCountFilter) { List dataBinFilters = fetchDataBinFilters(dataBinCountFilter); StudyViewFilter studyViewFilter = dataBinCountFilter.getStudyViewFilter(); @@ -609,12 +725,12 @@ public filteredSampleIds = new ArrayList<>(); List filteredStudyIds = new ArrayList<>(); List filteredData = fetchData(dataBinCountFilter, studyViewFilter, filteredSampleIds, - filteredStudyIds); + filteredStudyIds); List filteredUniqueSampleKeys = getUniqkeyKeys(filteredStudyIds, filteredSampleIds); Map> filteredClinicalDataByAttributeId = filteredData.stream() - .collect(Collectors.groupingBy(Binnable::getAttrId)); + .collect(Collectors.groupingBy(Binnable::getAttrId)); if (dataBinMethod == DataBinMethod.STATIC) { @@ -627,33 +743,33 @@ public unfilteredSampleIds = new ArrayList<>(); List unfilteredStudyIds = new ArrayList<>(); List unfilteredData = fetchData(dataBinCountFilter, filter, unfilteredSampleIds, - unfilteredStudyIds); + unfilteredStudyIds); List unFilteredUniqueSampleKeys = getUniqkeyKeys(unfilteredSampleIds, unfilteredStudyIds); Map> unfilteredDataByAttributeId = unfilteredData.stream() - .collect(Collectors.groupingBy(Binnable::getAttrId)); + .collect(Collectors.groupingBy(Binnable::getAttrId)); resultDataBins = dataBinFilters.stream().flatMap(dataBinFilter -> { - String attributeId = getAttributeUniqueKey(dataBinFilter); + String attributeId = studyViewFilterUtil.getDataBinFilterUniqueKey(dataBinFilter); return dataBinner - .calculateClinicalDataBins(dataBinFilter, ClinicalDataType.SAMPLE, - filteredClinicalDataByAttributeId.getOrDefault(attributeId, Collections.emptyList()), - unfilteredDataByAttributeId.getOrDefault(attributeId, Collections.emptyList()), - filteredUniqueSampleKeys, unFilteredUniqueSampleKeys) - .stream().map(dataBin -> (U) transform(dataBinFilter, dataBin)); + .calculateClinicalDataBins(dataBinFilter, ClinicalDataType.SAMPLE, + filteredClinicalDataByAttributeId.getOrDefault(attributeId, Collections.emptyList()), + unfilteredDataByAttributeId.getOrDefault(attributeId, Collections.emptyList()), + filteredUniqueSampleKeys, unFilteredUniqueSampleKeys) + .stream().map(dataBin -> (U) transform(dataBinFilter, dataBin)); }).collect(Collectors.toList()); } else { // dataBinMethod == DataBinMethod.DYNAMIC - resultDataBins = (List) dataBinFilters.stream().flatMap(dataBinFilter -> { - return dataBinner - .calculateDataBins(dataBinFilter, ClinicalDataType.SAMPLE, - filteredClinicalDataByAttributeId.getOrDefault(getAttributeUniqueKey(dataBinFilter), - Collections.emptyList()), - filteredUniqueSampleKeys) - .stream().map(dataBin -> (U) transform(dataBinFilter, dataBin)); - }).collect(Collectors.toList()); + resultDataBins = dataBinFilters.stream().flatMap(dataBinFilter -> + dataBinner + .calculateDataBins(dataBinFilter, ClinicalDataType.SAMPLE, + filteredClinicalDataByAttributeId.getOrDefault(studyViewFilterUtil.getDataBinFilterUniqueKey(dataBinFilter), + Collections.emptyList()), + filteredUniqueSampleKeys) + .stream().map(dataBin -> (U) transform(dataBinFilter, dataBin)) + ).collect(Collectors.toList()); } return resultDataBins; @@ -661,8 +777,8 @@ public List fetchData( S dataBinCountFilter, - StudyViewFilter studyViewFilter, - List sampleIds, + StudyViewFilter studyViewFilter, + List sampleIds, List studyIds ) { @@ -670,49 +786,49 @@ private List fetchData( studyViewFilterUtil.extractStudyAndSampleIds(filteredSampleIdentifiers, studyIds, sampleIds); List molecularProfiles = molecularProfileService.getMolecularProfilesInStudies(studyIds, - "SUMMARY"); + Projection.SUMMARY.name()); Map> molecularProfileMap = molecularProfileUtil .categorizeMolecularProfilesByStableIdSuffixes(molecularProfiles); - if (dataBinCountFilter instanceof GenomicDataBinCountFilter) { - GenomicDataBinCountFilter genomicDataBinCountFilter = (GenomicDataBinCountFilter) dataBinCountFilter; + if (dataBinCountFilter instanceof GenomicDataBinCountFilter genomicDataBinCountFilter) { List genomicDataBinFilters = genomicDataBinCountFilter.getGenomicDataBinFilters(); Set hugoGeneSymbols = genomicDataBinFilters.stream().map(GenomicDataBinFilter::getHugoGeneSymbol) - .collect(Collectors.toSet()); + .collect(Collectors.toSet()); Map geneSymbolIdMap = geneService - .fetchGenes(new ArrayList<>(hugoGeneSymbols), GeneIdType.HUGO_GENE_SYMBOL.name(), - Projection.SUMMARY.name()) - .stream().collect(Collectors.toMap(Gene::getHugoGeneSymbol, Gene::getEntrezGeneId)); + .fetchGenes(new ArrayList<>(hugoGeneSymbols), GeneIdType.HUGO_GENE_SYMBOL.name(), + Projection.SUMMARY.name()) + .stream().collect(Collectors.toMap(Gene::getHugoGeneSymbol, Gene::getEntrezGeneId)); - return genomicDataBinFilters.stream().flatMap(genomicDataFilter -> { + return genomicDataBinFilters.stream().flatMap(genomicDataBinFilter -> { Map studyIdToMolecularProfileIdMap = molecularProfileMap - .getOrDefault(genomicDataFilter.getProfileType(), new ArrayList()).stream() - .collect(Collectors.toMap(MolecularProfile::getCancerStudyIdentifier, - MolecularProfile::getStableId)); + .getOrDefault(genomicDataBinFilter.getProfileType(), new ArrayList<>()).stream() + .collect(Collectors.toMap(MolecularProfile::getCancerStudyIdentifier, + MolecularProfile::getStableId)); return invokeDataFunc(sampleIds, studyIds, - Arrays.asList(geneSymbolIdMap.get(genomicDataFilter.getHugoGeneSymbol()).toString()), - studyIdToMolecularProfileIdMap, genomicDataFilter, fetchMolecularData); + List.of(geneSymbolIdMap.get(genomicDataBinFilter.getHugoGeneSymbol()).toString()), + studyIdToMolecularProfileIdMap, studyViewFilterUtil.getDataBinFilterUniqueKey(genomicDataBinFilter), + fetchMolecularData); }).collect(Collectors.toList()); - } else if (dataBinCountFilter instanceof GenericAssayDataBinCountFilter) { + } else if (dataBinCountFilter instanceof GenericAssayDataBinCountFilter genomicDataBinCountFilter) { - GenericAssayDataBinCountFilter genomicDataBinCountFilter = (GenericAssayDataBinCountFilter) dataBinCountFilter; List genericAssayDataBinFilters = genomicDataBinCountFilter - .getGenericAssayDataBinFilters(); + .getGenericAssayDataBinFilters(); return genericAssayDataBinFilters.stream().flatMap(genericAssayDataBinFilter -> { Map studyIdToMolecularProfileIdMap = molecularProfileMap - .getOrDefault(genericAssayDataBinFilter.getProfileType(), new ArrayList()) - .stream().collect(Collectors.toMap(MolecularProfile::getCancerStudyIdentifier, - MolecularProfile::getStableId)); + .getOrDefault(genericAssayDataBinFilter.getProfileType(), new ArrayList<>()) + .stream().collect(Collectors.toMap(MolecularProfile::getCancerStudyIdentifier, + MolecularProfile::getStableId)); - return invokeDataFunc(sampleIds, studyIds, Arrays.asList(genericAssayDataBinFilter.getStableId()), - studyIdToMolecularProfileIdMap, genericAssayDataBinFilter, fetchGenericAssayData); + return invokeDataFunc(sampleIds, studyIds, Collections.singletonList(genericAssayDataBinFilter.getStableId()), + studyIdToMolecularProfileIdMap, studyViewFilterUtil.getDataBinFilterUniqueKey(genericAssayDataBinFilter), + fetchGenericAssayData); }).collect(Collectors.toList()); @@ -721,9 +837,9 @@ private List fetchData( return new ArrayList<>(); } - private Stream invokeDataFunc(List sampleIds, List studyIds, - List stableIds, Map studyIdToMolecularProfileIdMap, S genomicDataFilter, - FourParameterFunction, List, List, String, List> dataFunc) { + private Stream invokeDataFunc(List sampleIds, List studyIds, + List stableIds, Map studyIdToMolecularProfileIdMap, String attributeId, + FourParameterFunction, List, List, String, List> dataFunc) { List mappedSampleIds = new ArrayList<>(); List mappedProfileIds = new ArrayList<>(); @@ -739,50 +855,53 @@ private Stream invokeDataFunc(List { - public R apply(T t, U u, V v, W w); + R apply(T t, U u, V v, W w); } FourParameterFunction, List, List, String, List> fetchMolecularData = ( - mappedProfileIds, mappedSampleIds, stableIds, attributeId) -> { - return molecularDataService.getMolecularDataInMultipleMolecularProfiles(mappedProfileIds, mappedSampleIds, - stableIds.stream().map(Integer::parseInt).collect(Collectors.toList()), Projection.SUMMARY.name()) - .stream().map(geneMolecularData -> { - ClinicalData clinicalData = new ClinicalData(); - clinicalData.setAttrId(attributeId); - clinicalData.setAttrValue(geneMolecularData.getValue()); - clinicalData.setPatientId(geneMolecularData.getPatientId()); - clinicalData.setSampleId(geneMolecularData.getSampleId()); - clinicalData.setStudyId(geneMolecularData.getStudyId()); - return clinicalData; - }).collect(Collectors.toList()); - }; + mappedProfileIds, mappedSampleIds, stableIds, attributeId) -> + molecularDataService.getMolecularDataInMultipleMolecularProfiles(mappedProfileIds, mappedSampleIds, + stableIds.stream().map(Integer::parseInt).toList(), Projection.SUMMARY.name()) + .stream().map(geneMolecularData -> + transformDataToClinicalData(geneMolecularData, attributeId, geneMolecularData.getValue())) + .collect(Collectors.toList()); FourParameterFunction, List, List, String, List> fetchGenericAssayData = ( - mappedProfileIds, mappedSampleIds, stableIds, attributeId) -> { + mappedProfileIds, mappedSampleIds, stableIds, attributeId) -> { try { return genericAssayService - .fetchGenericAssayData(mappedProfileIds, mappedSampleIds, stableIds, Projection.SUMMARY.name()) - .stream().map(genericAssayData -> { - ClinicalData clinicalData = new ClinicalData(); - clinicalData.setAttrId(attributeId); - clinicalData.setAttrValue(genericAssayData.getValue()); - clinicalData.setPatientId(genericAssayData.getPatientId()); - clinicalData.setSampleId(genericAssayData.getSampleId()); - clinicalData.setStudyId(genericAssayData.getStudyId()); - return clinicalData; - }).collect(Collectors.toList()); + .fetchGenericAssayData(mappedProfileIds, mappedSampleIds, stableIds, Projection.SUMMARY.name()) + .stream().map(genericAssayData -> + transformDataToClinicalData(genericAssayData, attributeId, genericAssayData.getValue()) + ).collect(Collectors.toList()); } catch (MolecularProfileNotFoundException e) { return new ArrayList<>(); } }; + FourParameterFunction, List, List, String, List> fetchMutationData = ( + mappedProfileIds, mappedSampleIds, stableIds, attributeId) -> + mutationService.getMutationsInMultipleMolecularProfiles(mappedProfileIds, mappedSampleIds, + stableIds.stream().map(Integer::parseInt).toList(), Projection.DETAILED.name(), + null, null, null, null) + .stream().map(mutationData -> transformDataToClinicalData(mutationData, attributeId, mutationData.getMutationType().toUpperCase()) + ).collect(Collectors.toList()); + + FourParameterFunction, List, List, String, List> fetchMutatedData = ( + mappedProfileIds, mappedSampleIds, stableIds, attributeId) -> + mutationService.getMutationsInMultipleMolecularProfiles(mappedProfileIds, mappedSampleIds, + stableIds.stream().map(Integer::parseInt).toList(), Projection.DETAILED.name(), + null, null, null, null) + .stream().map(mutationData -> transformDataToClinicalData(mutationData, attributeId, MutationFilterOption.MUTATED.name()) + ).collect(Collectors.toList()); + private List fetchDataBinFilters(T dataBinCountFilter) { if (dataBinCountFilter instanceof GenomicDataBinCountFilter) { return (List) ((GenomicDataBinCountFilter) dataBinCountFilter).getGenomicDataBinFilters(); @@ -794,43 +913,26 @@ private List fetchDat private void removeSelfFromFilter(S dataBinFilter, StudyViewFilter studyViewFilter) { if (studyViewFilter != null) { - if (dataBinFilter instanceof GenomicDataBinFilter) { - GenomicDataBinFilter genomicDataBinFilter = (GenomicDataBinFilter) dataBinFilter; - if (studyViewFilter.getGenomicDataFilters() != null) { - studyViewFilter.getGenomicDataFilters().removeIf(f -> { - return f.getHugoGeneSymbol().equals(genomicDataBinFilter.getHugoGeneSymbol()) - && f.getProfileType().equals(genomicDataBinFilter.getProfileType()); - }); - } - } else if (dataBinFilter instanceof GenericAssayDataBinFilter) { - GenericAssayDataBinFilter genericAssayDataBinFilter = (GenericAssayDataBinFilter) dataBinFilter; - if (studyViewFilter.getGenericAssayDataFilters() != null) { - studyViewFilter.getGenericAssayDataFilters().removeIf(f -> { - return f.getStableId().equals(genericAssayDataBinFilter.getStableId()) - && f.getProfileType().equals(genericAssayDataBinFilter.getProfileType()); - }); - } + if (dataBinFilter instanceof GenomicDataBinFilter genomicDataBinFilter && + studyViewFilter.getGenomicDataFilters() != null) { + studyViewFilter.getGenomicDataFilters().removeIf(f -> + f.getHugoGeneSymbol().equals(genomicDataBinFilter.getHugoGeneSymbol()) + && f.getProfileType().equals(genomicDataBinFilter.getProfileType()) + ); + } else if (dataBinFilter instanceof GenericAssayDataBinFilter genericAssayDataBinFilter && + studyViewFilter.getGenericAssayDataFilters() != null) { + studyViewFilter.getGenericAssayDataFilters().removeIf(f -> + f.getStableId().equals(genericAssayDataBinFilter.getStableId()) + && f.getProfileType().equals(genericAssayDataBinFilter.getProfileType()) + ); } } } - private String getAttributeUniqueKey(S dataBinFilter) { - if (dataBinFilter instanceof GenomicDataBinFilter) { - GenomicDataBinFilter genomicDataBinFilter = (GenomicDataBinFilter) dataBinFilter; - return genomicDataBinFilter.getHugoGeneSymbol() + genomicDataBinFilter.getProfileType(); - } else if (dataBinFilter instanceof GenericAssayDataBinFilter) { - GenericAssayDataBinFilter genericAssayDataBinFilter = (GenericAssayDataBinFilter) dataBinFilter; - return genericAssayDataBinFilter.getStableId() + genericAssayDataBinFilter.getProfileType(); - } - return null; - } - private T transform(S dataBinFilter, DataBin dataBin) { - if (dataBinFilter instanceof GenomicDataBinFilter) { - GenomicDataBinFilter genomicDataBinFilter = (GenomicDataBinFilter) dataBinFilter; + if (dataBinFilter instanceof GenomicDataBinFilter genomicDataBinFilter) { return (T) dataBintoGenomicDataBin(genomicDataBinFilter, dataBin); - } else if (dataBinFilter instanceof GenericAssayDataBinFilter) { - GenericAssayDataBinFilter genericAssayDataBinFilter = (GenericAssayDataBinFilter) dataBinFilter; + } else if (dataBinFilter instanceof GenericAssayDataBinFilter genericAssayDataBinFilter) { return (T) dataBintoGenericAssayDataBin(genericAssayDataBinFilter, dataBin); } return null; @@ -854,7 +956,7 @@ private GenomicDataBin dataBintoGenomicDataBin(GenomicDataBinFilter genomicDataB } private GenericAssayDataBin dataBintoGenericAssayDataBin(GenericAssayDataBinFilter genericAssayDataBinFilter, - DataBin dataBin) { + DataBin dataBin) { GenericAssayDataBin genericAssayDataBin = new GenericAssayDataBin(); genericAssayDataBin.setCount(dataBin.getCount()); genericAssayDataBin.setStableId(genericAssayDataBinFilter.getStableId()); @@ -873,14 +975,14 @@ private GenericAssayDataBin dataBintoGenericAssayDataBin(GenericAssayDataBinFilt public List intervalFilterExpressionData( List sampleIdentifiers, List molecularProfiles, List dataFilters, - Boolean negateFilters) { + boolean negateFilters) { return filterExpressionData(sampleIdentifiers, molecularProfiles, dataFilters, negateFilters, clinicalDataIntervalFilterApplier); } public List equalityFilterExpressionData( List sampleIdentifiers, List molecularProfiles, List dataFilters, - Boolean negateFilters) { + boolean negateFilters) { return filterExpressionData(sampleIdentifiers, molecularProfiles, dataFilters, negateFilters, clinicalDataEqualityFilterApplier); } @@ -888,35 +990,25 @@ public List equalityFilterExpressionDat public List filterExpressionData( List sampleIdentifiers, List molecularProfiles, List dataFilters, - Boolean negateFilters, ClinicalDataFilterApplier clinicalDataFilterApplier) { + boolean negateFilters, ClinicalDataFilterApplier clinicalDataFilterApplier) { if (!CollectionUtils.isEmpty(dataFilters) && !CollectionUtils.isEmpty(sampleIdentifiers)) { List clinicalDatas = fetchDataAndTransformToClinicalDataList(sampleIdentifiers, molecularProfiles, dataFilters); - List attributes =transformToClinicalDataFilter(dataFilters); - - MultiKeyMap clinicalDataMap = new MultiKeyMap(); + List attributes = transformToClinicalDataFilter(dataFilters); - clinicalDatas.forEach(clinicalData -> { - clinicalDataMap.put(clinicalData.getStudyId(), clinicalData.getSampleId(), clinicalData.getAttrId(), - clinicalData.getAttrValue()); - }); - - List newSampleIdentifiers = new ArrayList<>(); - for (SampleIdentifier sampleIdentifier : sampleIdentifiers) { - int count = clinicalDataFilterApplier.apply(attributes, clinicalDataMap, - sampleIdentifier.getSampleId(), sampleIdentifier.getStudyId(), negateFilters); - - if (count == attributes.size()) { - newSampleIdentifiers.add(sampleIdentifier); - } + MultiKeyMap clinicalDataMap; + if (clinicalDataFilterApplier instanceof ClinicalDataEqualityFilterApplier) { + clinicalDataMap = ClinicalDataEqualityFilterApplier.buildClinicalDataMap(clinicalDatas); + } else { + clinicalDataMap = ClinicalDataIntervalFilterApplier.buildClinicalDataMap(clinicalDatas); } - return newSampleIdentifiers; + return filterSampleIdentifiers(sampleIdentifiers, attributes, clinicalDataMap, clinicalDataFilterApplier, negateFilters).stream().distinct().toList(); } return sampleIdentifiers; } - + private List fetchDataAndTransformToClinicalDataList( List sampleIdentifiers, List molecularProfiles, List dataFilters) { Map> molecularProfileMap = molecularProfileUtil @@ -925,8 +1017,8 @@ private List fetchDataAndTransformToClinica List studyIds = new ArrayList<>(); List sampleIds = new ArrayList<>(); studyViewFilterUtil.extractStudyAndSampleIds(sampleIdentifiers, studyIds, sampleIds); - - if (dataFilters.get(0) instanceof GenomicDataFilter) { + + if (dataFilters.getFirst() instanceof GenomicDataFilter) { List genomicDataIntervalFilters = (List) dataFilters; Set hugoGeneSymbols = genomicDataIntervalFilters.stream() .map(GenomicDataFilter::getHugoGeneSymbol).collect(Collectors.toSet()); @@ -937,34 +1029,29 @@ private List fetchDataAndTransformToClinica return genomicDataIntervalFilters.stream().flatMap(genomicDataFilter -> { - Map studyIdToMolecularProfileIdMap = molecularProfileMap - .getOrDefault(genomicDataFilter.getProfileType(), new ArrayList<>()) + List subMolecularProfiles = molecularProfileMap + .getOrDefault(genomicDataFilter.getProfileType(), new ArrayList<>()); + Map studyIdToMolecularProfileIdMap = subMolecularProfiles .stream().collect(Collectors.toMap(MolecularProfile::getCancerStudyIdentifier, MolecularProfile::getStableId)); - GenomicDataBinFilter genomicDataBinFilter = new GenomicDataBinFilter(); - genomicDataBinFilter.setHugoGeneSymbol(genomicDataFilter.getHugoGeneSymbol()); - genomicDataBinFilter.setProfileType(genomicDataFilter.getProfileType()); return invokeDataFunc(sampleIds, studyIds, Collections.singletonList(geneNameIdMap.get(genomicDataFilter.getHugoGeneSymbol()).toString()), - studyIdToMolecularProfileIdMap, genomicDataBinFilter, fetchMolecularData); + studyIdToMolecularProfileIdMap, studyViewFilterUtil.getDataFilterUniqueKey(genomicDataFilter), + fetchMolecularData); }).collect(Collectors.toList()); } else { - return ((List) dataFilters).stream().flatMap(genericAssayDataFilter -> { Map studyIdToMolecularProfileIdMap = molecularProfileMap .getOrDefault(genericAssayDataFilter.getProfileType(), new ArrayList()) .stream().collect(Collectors.toMap(MolecularProfile::getCancerStudyIdentifier, MolecularProfile::getStableId)); - GenericAssayDataBinFilter genericAssayDataBinFilter = new GenericAssayDataBinFilter(); - genericAssayDataBinFilter.setStableId(genericAssayDataFilter.getStableId()); - genericAssayDataBinFilter.setProfileType(genericAssayDataFilter.getProfileType()); // get original data stream from invokeDataFunc - Stream dataStream = invokeDataFunc(sampleIds, studyIds, Collections.singletonList(genericAssayDataBinFilter.getStableId()), - studyIdToMolecularProfileIdMap, genericAssayDataBinFilter, fetchGenericAssayData); + Stream dataStream = invokeDataFunc(sampleIds, studyIds, Collections.singletonList(genericAssayDataFilter.getStableId()), + studyIdToMolecularProfileIdMap, studyViewFilterUtil.getDataFilterUniqueKey(genericAssayDataFilter), fetchGenericAssayData); // For patient level generic assay profile, only keep the one sample per patient List profiles = molecularProfileMap.getOrDefault(genericAssayDataFilter.getProfileType(), new ArrayList<>()); if (profiles.size() > 0 && profiles.get(0).getPatientLevel()) { @@ -974,28 +1061,238 @@ private List fetchDataAndTransformToClinica // don't change anything for non patient level data return dataStream; }).collect(Collectors.toList()); - } } - private List transformToClinicalDataFilter(List dataFilters) { - List attributes; - attributes = dataFilters.stream().map(dataFilter -> { - String attributeId; - if (dataFilter instanceof GenomicDataFilter) { - GenomicDataFilter genomicDataFilter = (GenomicDataFilter) dataFilter; - attributeId = studyViewFilterUtil.getGenomicDataFilterUniqueKey(genomicDataFilter.getHugoGeneSymbol(), genomicDataFilter.getProfileType()); + private List fetchMutationDataAndTransformToClinicalDataList( + List sampleIdentifiers, List molecularProfiles, List mutationDataFilters + ) { + Map> molecularProfileMap = molecularProfileUtil + .categorizeMolecularProfilesByStableIdSuffixes(molecularProfiles); + + List studyIds = new ArrayList<>(); + List sampleIds = new ArrayList<>(); + studyViewFilterUtil.extractStudyAndSampleIds(sampleIdentifiers, studyIds, sampleIds); + + Set hugoGeneSymbols = mutationDataFilters.stream() + .map(MutationDataFilter::getHugoGeneSymbol).collect(Collectors.toSet()); + Map geneNameIdMap = geneService + .fetchGenes(new ArrayList<>(hugoGeneSymbols), GeneIdType.HUGO_GENE_SYMBOL.name(), + Projection.SUMMARY.name()) + .stream().collect(Collectors.toMap(Gene::getHugoGeneSymbol, Gene::getEntrezGeneId)); + + return mutationDataFilters.stream().flatMap(mutationDataFilter -> { + List subMolecularProfiles = molecularProfileMap + .getOrDefault(mutationDataFilter.getProfileType(), new ArrayList<>()); + Map studyIdToMolecularProfileIdMap = subMolecularProfiles + .stream().collect(Collectors.toMap(MolecularProfile::getCancerStudyIdentifier, + MolecularProfile::getStableId)); + + if (mutationDataFilter.getCategorization() == MutationOption.MUTATED) { + return fetchMutatedAndWildTypeData( + sampleIdentifiers, geneNameIdMap, mutationDataFilter, + studyIdToMolecularProfileIdMap); } else { - GenericAssayDataFilter genericAssayDataFilter = (GenericAssayDataFilter) dataFilter; - attributeId = studyViewFilterUtil.getGenericAssayDataFilterUniqueKey( - genericAssayDataFilter.getStableId(), genericAssayDataFilter.getProfileType()); + // fetch mutation type data + return invokeDataFunc(sampleIds, studyIds, Collections.singletonList( + geneNameIdMap.get(mutationDataFilter.getHugoGeneSymbol()).toString()), + studyIdToMolecularProfileIdMap, + studyViewFilterUtil.getMutationDataFilterUniqueKey(mutationDataFilter), + fetchMutationData); } + }).collect(Collectors.toList()); + } + private List transformToClinicalDataFilter(List dataFilters) { + List attributes; + attributes = dataFilters.stream().map(dataFilter -> { ClinicalDataFilter clinicalDataFilter = new ClinicalDataFilter(); - clinicalDataFilter.setAttributeId(attributeId); + clinicalDataFilter.setAttributeId(studyViewFilterUtil.getDataFilterUniqueKey(dataFilter)); clinicalDataFilter.setValues(dataFilter.getValues()); return clinicalDataFilter; }).collect(Collectors.toList()); return attributes; } + + private List fetchProfiledMutationDataByGene(List studyIds, List sampleIds, Integer entrezGeneId) { + List molecularProfileCaseIdentifiers = + molecularProfileService.getMutationProfileCaseIdentifiers(studyIds, sampleIds); + + List genePanelDataList = genePanelService + .fetchGenePanelDataInMultipleMolecularProfiles(molecularProfileCaseIdentifiers); + + Function sampleIdentifierBuilder = sample -> + studyViewFilterUtil.buildSampleIdentifier(sample.getStudyId(), sample.getSampleId()); + + Map> casesWithDataInGenePanel = new HashMap<>(); + // loop through all membership records -- ignore any where g.getGenePanelId == null + for (GenePanelData genePanelDataRecord : genePanelDataList) { + String associatedGenePanel = genePanelDataRecord.getGenePanelId(); + if (associatedGenePanel != null) { + casesWithDataInGenePanel.putIfAbsent(associatedGenePanel, new HashSet<>()); + Set casesForThisGenePanel = casesWithDataInGenePanel.get(associatedGenePanel); + casesForThisGenePanel.add(sampleIdentifierBuilder.apply(genePanelDataRecord)); + } + } + + List genePanels = new ArrayList<>(); + if (!casesWithDataInGenePanel.isEmpty()) { + genePanels = genePanelService.fetchGenePanels(new ArrayList<>(casesWithDataInGenePanel.keySet()), Projection.DETAILED.name()); + } + + List genePanelData = genePanelDataList + .stream() + .filter(GenePanelData::getProfiled) + .toList(); + + Set profiledCases = genePanelData + .stream() + // there can be duplicate patient or sample id, append study id + .map(sampleIdentifierBuilder) + .collect(Collectors.toSet()); + + // here we look for cases where none of the profiles have gene panel ids + // a case with at least one profile with gene panel id is considered as a case with gene panel data + // so a case is considered without panel data only if none of the profiles has a gene panel id + + // first identify cases with gene panel data + Set casesWithPanelData = genePanelData + .stream() + .filter(g -> g.getGenePanelId() != null) + // there can be duplicate patient or sample id, append study id + .map(sampleIdentifierBuilder) + .collect(Collectors.toSet()); + + // find all unique cases + Set casesWithoutPanelData = genePanelData + .stream() + // there can be duplicate patient or sample id, append study id + .map(sampleIdentifierBuilder) + .collect(Collectors.toSet()); + + // removing cases with panel data from all unique cases gives us the cases without panel data + casesWithoutPanelData.removeAll(casesWithPanelData); + + List genePanelIds = genePanels.stream().flatMap(genePanel -> { + List genePanelToGenes = genePanel.getGenes(); + return genePanelToGenes + .stream() + .filter(genePanelToGene -> genePanelToGene.getEntrezGeneId().equals(entrezGeneId)) + .map(GenePanelToGene::getGenePanelId); + }).toList(); + + List newSampleIdentifiers = new ArrayList<>(); + // different calculations depending on if gene is linked to gene panels + if (CollectionUtils.isNotEmpty(genePanelIds)) { + // for every gene panel associated containing the gene, use the sum of unique cases + // as well as cases without panel data + for (String genePanelId : genePanelIds) { + newSampleIdentifiers.addAll(casesWithDataInGenePanel.get(genePanelId)); + } + newSampleIdentifiers.addAll(casesWithoutPanelData); + } else { + // we use profiledCasesCount instead of casesWithoutPanelData to + // prevent a divide by zero error which can happen for targeted studies + // in which certain genes have events that are not captured by the panel. + newSampleIdentifiers.addAll(profiledCases); + } + + return newSampleIdentifiers; + } + + private Stream fetchMutatedAndWildTypeData( + List sampleIdentifiers, Map geneNameIdMap, MutationDataFilter mutationDataFilter, + Map studyIdToMolecularProfileIdMap) { + List studyIds = new ArrayList<>(); + List sampleIds = new ArrayList<>(); + studyViewFilterUtil.extractStudyAndSampleIds(sampleIdentifiers, studyIds, sampleIds); + + // mutated + List mutatedClinicalDatas = invokeDataFunc(sampleIds, studyIds, + Collections.singletonList(geneNameIdMap.get(mutationDataFilter.getHugoGeneSymbol()).toString()), + studyIdToMolecularProfileIdMap, studyViewFilterUtil.getMutationDataFilterUniqueKey(mutationDataFilter), + fetchMutatedData).toList(); + + List mutatedSampleIdentifiers = mutatedClinicalDatas + .stream() + .map(datum -> studyViewFilterUtil.buildSampleIdentifier(datum.getStudyId(), datum.getSampleId()) + ).toList(); + + List clinicalDatas = new ArrayList<>(mutatedClinicalDatas); + + // not profiled + List profiledSampleIdentifiers = fetchProfiledMutationDataByGene( + studyIds, sampleIds, geneNameIdMap.get(mutationDataFilter.getHugoGeneSymbol())); + + List notProfiledSampleIdentifiers = sampleIdentifiers + .stream() + .filter(s -> profiledSampleIdentifiers.stream().noneMatch(p -> p.equals(s))) + .toList(); + + List notProfiledClinicalDatas = studyViewFilterUtil.transformSampleIdentifiersToClinicalData( + notProfiledSampleIdentifiers, + studyViewFilterUtil.getMutationDataFilterUniqueKey(mutationDataFilter), + MutationFilterOption.NOT_PROFILED.name() + ); + + clinicalDatas.addAll(notProfiledClinicalDatas); + + // not mutated + List notMutatedSampleIdentifiers = profiledSampleIdentifiers + .stream() + .filter(p -> mutatedSampleIdentifiers.stream().noneMatch(m -> m.equals(p))) + .toList(); + + List notMutatedClinicalDatas = studyViewFilterUtil.transformSampleIdentifiersToClinicalData( + notMutatedSampleIdentifiers, + studyViewFilterUtil.getMutationDataFilterUniqueKey(mutationDataFilter), + MutationFilterOption.NOT_MUTATED.name() + ); + + clinicalDatas.addAll(notMutatedClinicalDatas); + + return clinicalDatas.stream(); + } + + private ClinicalData transformDataToClinicalData(S data, String attributeId, String attributeValue) { + ClinicalData clinicalData = new ClinicalData(); + + if (data instanceof MolecularData molecularData) { + clinicalData.setPatientId(molecularData.getPatientId()); + clinicalData.setSampleId(molecularData.getSampleId()); + clinicalData.setStudyId(molecularData.getStudyId()); + } else if (data instanceof Mutation mutationData) { + clinicalData.setPatientId(mutationData.getPatientId()); + clinicalData.setSampleId(mutationData.getSampleId()); + clinicalData.setStudyId(mutationData.getStudyId()); + } else { + return clinicalData; + } + + clinicalData.setAttrValue(attributeValue); + clinicalData.setAttrId(attributeId); + + return clinicalData; + } + + private List filterSampleIdentifiers( + List sampleIdentifiers, + List attributes, + MultiKeyMap clinicalDataMap, + ClinicalDataFilterApplier clinicalDataFilterApplier, + boolean negateFilters + ) { + return sampleIdentifiers.stream() + .filter(sampleIdentifier -> { + int count = clinicalDataFilterApplier.apply( + attributes, + clinicalDataMap, + sampleIdentifier.getSampleId(), + sampleIdentifier.getStudyId(), + negateFilters + ); + return count == attributes.size(); + }) + .collect(Collectors.toList()); + } } diff --git a/src/main/java/org/cbioportal/web/util/StudyViewFilterUtil.java b/src/main/java/org/cbioportal/web/util/StudyViewFilterUtil.java index ecf5bdab85c..972aa31436b 100644 --- a/src/main/java/org/cbioportal/web/util/StudyViewFilterUtil.java +++ b/src/main/java/org/cbioportal/web/util/StudyViewFilterUtil.java @@ -1,12 +1,9 @@ package org.cbioportal.web.util; -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; - import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.map.MultiKeyMap; import org.cbioportal.model.Binnable; +import org.cbioportal.model.ClinicalData; import org.cbioportal.model.ClinicalDataBin; import org.cbioportal.model.ClinicalDataCount; import org.cbioportal.model.ClinicalDataCountItem; @@ -21,10 +18,32 @@ import org.cbioportal.service.util.CustomDataSession; import org.cbioportal.service.util.CustomDataValue; import org.cbioportal.service.util.MolecularProfileUtil; -import org.cbioportal.web.parameter.*; +import org.cbioportal.web.parameter.ClinicalDataBinFilter; +import org.cbioportal.web.parameter.ClinicalDataFilter; +import org.cbioportal.web.parameter.DataBinFilter; +import org.cbioportal.web.parameter.DataFilter; +import org.cbioportal.web.parameter.DataFilterValue; +import org.cbioportal.web.parameter.GeneIdType; +import org.cbioportal.web.parameter.GenericAssayDataBinFilter; +import org.cbioportal.web.parameter.GenericAssayDataFilter; +import org.cbioportal.web.parameter.GenomicDataBinFilter; +import org.cbioportal.web.parameter.GenomicDataFilter; +import org.cbioportal.web.parameter.MutationDataFilter; +import org.cbioportal.web.parameter.MutationOption; +import org.cbioportal.web.parameter.Projection; +import org.cbioportal.web.parameter.SampleIdentifier; +import org.cbioportal.web.parameter.StudyViewFilter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + @Component public class StudyViewFilterUtil { @Autowired @@ -32,10 +51,10 @@ public class StudyViewFilterUtil { @Autowired private GeneService geneService; - + public void extractStudyAndSampleIds( - List sampleIdentifiers, - List studyIds, + List sampleIdentifiers, + List studyIds, List sampleIds ) { for (SampleIdentifier sampleIdentifier : sampleIdentifiers) { @@ -49,15 +68,25 @@ public void removeSelfFromFilter(String attributeId, StudyViewFilter studyViewFi studyViewFilter.getClinicalDataFilters().removeIf(f -> f.getAttributeId().equals(attributeId)); } } - + public void removeSelfFromGenomicDataFilter(String hugoGeneSymbol, String profileType, StudyViewFilter studyViewFilter) { if (studyViewFilter != null && studyViewFilter.getGenomicDataFilters() != null) { - studyViewFilter.getGenomicDataFilters().removeIf(f -> + studyViewFilter.getGenomicDataFilters().removeIf(f -> f.getHugoGeneSymbol().equals(hugoGeneSymbol) && f.getProfileType().equals(profileType) ); } } + public void removeSelfFromMutationDataFilter(String hugoGeneSymbol, String profileType, MutationOption categorization, StudyViewFilter studyViewFilter) { + if (studyViewFilter != null && studyViewFilter.getMutationDataFilters() != null) { + studyViewFilter.getMutationDataFilters().removeIf(f -> + f.getHugoGeneSymbol().equals(hugoGeneSymbol) && + f.getProfileType().equals(profileType) && + f.getCategorization().equals(categorization) + ); + } + } + public void removeSelfFromGenericAssayFilter(String stableId, StudyViewFilter studyViewFilter) { if (studyViewFilter != null && studyViewFilter.getGenericAssayDataFilters() != null) { studyViewFilter.getGenericAssayDataFilters().removeIf(f -> f.getStableId().equals(stableId)); @@ -69,17 +98,31 @@ public void removeSelfCustomDataFromFilter(String attributeId, StudyViewFilter s studyViewFilter.getCustomDataFilters().removeIf(f -> f.getAttributeId().equals(attributeId)); } } - + public String getCaseUniqueKey(String studyId, String caseId) { return studyId + caseId; } - public String getGenomicDataFilterUniqueKey(String hugoGeneSymbol, String profileType) { - return hugoGeneSymbol + profileType; + public String getDataFilterUniqueKey(S dataFilter) { + if (dataFilter instanceof GenomicDataFilter genomicDataFilter) { + return genomicDataFilter.getHugoGeneSymbol() + genomicDataFilter.getProfileType(); + } else if (dataFilter instanceof GenericAssayDataFilter genericAssayDataFilter) { + return genericAssayDataFilter.getStableId() + genericAssayDataFilter.getProfileType(); + } + return null; + } + + public String getMutationDataFilterUniqueKey(MutationDataFilter mutationDataFilter) { + return mutationDataFilter.getHugoGeneSymbol() + mutationDataFilter.getProfileType(); } - public String getGenericAssayDataFilterUniqueKey(String stableId, String profileType) { - return stableId + profileType; + public String getDataBinFilterUniqueKey(S dataBinFilter) { + if (dataBinFilter instanceof GenomicDataBinFilter genomicDataBinFilter) { + return genomicDataBinFilter.getHugoGeneSymbol() + genomicDataBinFilter.getProfileType(); + } else if (dataBinFilter instanceof GenericAssayDataBinFilter genericAssayDataBinFilter) { + return genericAssayDataBinFilter.getStableId() + genericAssayDataBinFilter.getProfileType(); + } + return null; } public ClinicalDataBin dataBinToClinicalDataBin(ClinicalDataBinFilter attribute, DataBin dataBin) { @@ -104,18 +147,23 @@ public Map> categorizeSampleLists(List samp })); } - public Integer getFilteredCountByDataEquality(List attributes, MultiKeyMap clinicalDataMap, - String entityId, String studyId, Boolean negateFilters) { + public Integer getFilteredCountByDataEquality(List attributes, MultiKeyMap clinicalDataMap, + String entityId, String studyId, boolean negateFilters) { Integer count = 0; for (ClinicalDataFilter s : attributes) { List filteredValues = s.getValues() - .stream() - .map(DataFilterValue::getValue) - .collect(Collectors.toList()); + .stream() + .map(DataFilterValue::getValue) + .collect(Collectors.toList()); filteredValues.replaceAll(String::toUpperCase); if (clinicalDataMap.containsKey(studyId, entityId, s.getAttributeId())) { - String value = (String) clinicalDataMap.get(studyId, entityId, s.getAttributeId()); - if (negateFilters ^ filteredValues.contains(value)) { + S value = clinicalDataMap.get(studyId, entityId, s.getAttributeId()); + if (value instanceof String) { + if (negateFilters ^ filteredValues.contains(value)) { + count++; + } + } else if (value instanceof List && + negateFilters ^ filteredValues.stream().anyMatch(((List) value)::contains)) { count++; } } else if (negateFilters ^ filteredValues.contains("NA")) { @@ -126,7 +174,7 @@ public Integer getFilteredCountByDataEquality(List attribute } public List getClinicalDataCountsFromCustomData(Collection customDataSessions, - Map filteredSamplesMap, List patients) { + Map filteredSamplesMap, List patients) { int totalSamplesCount = filteredSamplesMap.keySet().size(); int totalPatientsCount = patients.size(); @@ -141,22 +189,22 @@ public List getClinicalDataCountsFromCustomData(Collectio clinicalDataCountItem.setAttributeId(customDataSession.getId()); List clinicalDataCounts = groupedDatabyValue.entrySet().stream() - .map(entry -> { - long count = entry.getValue().stream().map(datum -> { - return getCaseUniqueKey(datum.getStudyId(), - customDataSession.getData().getPatientAttribute() - ? datum.getPatientId() - : datum.getSampleId()); - - }).distinct().count(); - ClinicalDataCount dataCount = new ClinicalDataCount(); - dataCount.setValue(entry.getKey()); - dataCount.setCount(Math.toIntExact(count)); - return dataCount; - }) - .filter(c -> !c.getValue().equalsIgnoreCase("NA") && !c.getValue().equalsIgnoreCase("NAN") - && !c.getValue().equalsIgnoreCase("N/A")) - .collect(Collectors.toList()); + .map(entry -> { + long count = entry.getValue().stream().map(datum -> { + return getCaseUniqueKey(datum.getStudyId(), + customDataSession.getData().getPatientAttribute() + ? datum.getPatientId() + : datum.getSampleId()); + + }).distinct().count(); + ClinicalDataCount dataCount = new ClinicalDataCount(); + dataCount.setValue(entry.getKey()); + dataCount.setCount(Math.toIntExact(count)); + return dataCount; + }) + .filter(c -> !c.getValue().equalsIgnoreCase("NA") && !c.getValue().equalsIgnoreCase("NAN") + && !c.getValue().equalsIgnoreCase("N/A")) + .collect(Collectors.toList()); int totalCount = clinicalDataCounts.stream().mapToInt(ClinicalDataCount::getCount).sum(); int naCount = 0; @@ -177,38 +225,38 @@ public List getClinicalDataCountsFromCustomData(Collectio return clinicalDataCountItem; }).collect(Collectors.toList()); } - - public boolean isSingleStudyUnfiltered(StudyViewFilter filter) { - return filter.getStudyIds() != null && - filter.getStudyIds().size() == 1 && - (filter.getClinicalDataFilters() == null || filter.getClinicalDataFilters().isEmpty()) && - (filter.getGeneFilters() == null || filter.getGeneFilters().isEmpty()) && - (filter.getSampleTreatmentFilters() == null || filter.getSampleTreatmentFilters().getFilters().isEmpty()) && - (filter.getPatientTreatmentFilters() == null || filter.getPatientTreatmentFilters().getFilters().isEmpty()) && - (filter.getGenomicProfiles() == null || filter.getGenomicProfiles().isEmpty()) && - (filter.getGenomicDataFilters() == null || filter.getGenomicDataFilters().isEmpty()) && - (filter.getGenericAssayDataFilters() == null || filter.getGenericAssayDataFilters().isEmpty()) && - (filter.getCaseLists() == null || filter.getCaseLists().isEmpty()) && - (filter.getCustomDataFilters() == null || filter.getCustomDataFilters().isEmpty()); + + public boolean isUnfilteredQuery(StudyViewFilter filter) { + return filter.getStudyIds() != null && + (filter.getClinicalDataFilters() == null || filter.getClinicalDataFilters().isEmpty()) && + (filter.getGeneFilters() == null || filter.getGeneFilters().isEmpty()) && + (filter.getSampleTreatmentFilters() == null || filter.getSampleTreatmentFilters().getFilters().isEmpty()) && + (filter.getPatientTreatmentFilters() == null || filter.getPatientTreatmentFilters().getFilters().isEmpty()) && + (filter.getGenomicProfiles() == null || filter.getGenomicProfiles().isEmpty()) && + (filter.getGenomicDataFilters() == null || filter.getGenomicDataFilters().isEmpty()) && + (filter.getGenericAssayDataFilters() == null || filter.getGenericAssayDataFilters().isEmpty()) && + (filter.getCaseLists() == null || filter.getCaseLists().isEmpty()) && + (filter.getCustomDataFilters() == null || filter.getCustomDataFilters().isEmpty()) && + (filter.getMutationDataFilters() == null || filter.getMutationDataFilters().isEmpty()); } - + public boolean shouldSkipFilterForClinicalDataBins(StudyViewFilter filter) { // if everything other than study ids and sample identifiers is null, // we can skip the filter for data bin calculation return ( filter != null && - filter.getClinicalDataFilters() == null && - filter.getGeneFilters() == null && - filter.getSampleTreatmentFilters() == null && - filter.getPatientTreatmentFilters() == null && - filter.getGenomicProfiles() == null && - filter.getGenomicDataFilters() == null && - filter.getGenericAssayDataFilters() == null && - filter.getCaseLists() == null && - filter.getCustomDataFilters() == null + filter.getClinicalDataFilters() == null && + filter.getGeneFilters() == null && + filter.getSampleTreatmentFilters() == null && + filter.getPatientTreatmentFilters() == null && + filter.getGenomicProfiles() == null && + filter.getGenomicDataFilters() == null && + filter.getGenericAssayDataFilters() == null && + filter.getCaseLists() == null && + filter.getCustomDataFilters() == null ); } - + public List filterClinicalData( List unfilteredClinicalDataForSamples, List unfilteredClinicalDataForPatients, @@ -222,9 +270,9 @@ public List filterClinicalData( List conflictingPatientAttributes ) { List combinedResult = new ArrayList<>(); - + Map patientIdToStudyId = null; - + if (CollectionUtils.isNotEmpty(sampleAttributeIds)) { // create lookups for faster filtering Map sampleIdToStudyId = mapCaseToStudy(sampleIds, studyIds); @@ -243,7 +291,7 @@ public List filterClinicalData( // create lookups for faster filtering Map patientAttributeIdLookup = listToMap(patientAttributeIds); patientIdToStudyId = mapCaseToStudy(patientIds, studyIdsOfPatients); - + combinedResult.addAll( filterClinicalDataByStudyAndPatientAndAttribute( unfilteredClinicalDataForPatients, @@ -259,7 +307,7 @@ public List filterClinicalData( if (patientIdToStudyId == null) { patientIdToStudyId = mapCaseToStudy(patientIds, studyIdsOfPatients); } - + combinedResult.addAll( filterClinicalDataByStudyAndPatientAndAttribute( unfilteredClinicalDataForConflictingPatientAttributes, @@ -323,7 +371,7 @@ public List resolveEntrezGeneIds(List (q.getGene1Query().getSpecialValue() != StructuralVariantSpecialValue.NO_GENE + q -> (q.getGene1Query().getSpecialValue() != StructuralVariantSpecialValue.NO_GENE && q.getGene1Query().getSpecialValue() != StructuralVariantSpecialValue.ANY_GENE && q.getGene1Query().getEntrezId() == null) || (q.getGene2Query().getSpecialValue() != StructuralVariantSpecialValue.NO_GENE @@ -352,7 +400,7 @@ private List filterClinicalDataByStudyAndSampleAndAttribute( .stream() .filter(d -> sampleToStudyId.getOrDefault(generateSampleToStudyKey(d), "").equals(d.getStudyId()) && - attributeIdLookup.getOrDefault(d.getAttrId(), false) + attributeIdLookup.getOrDefault(d.getAttrId(), false) ) .collect(Collectors.toList()); } @@ -366,38 +414,57 @@ private List filterClinicalDataByStudyAndPatientAndAttribute( .stream() .filter(d -> patientToStudyId.getOrDefault(generatePatientToStudyKey(d), "").equals(d.getStudyId()) && - attributeIdLookup.getOrDefault(d.getAttrId(), false) + attributeIdLookup.getOrDefault(d.getAttrId(), false) ) .collect(Collectors.toList()); } - + private Map listToMap(List list) { return list.stream().collect(Collectors.toMap(s -> s, s -> true, (s1, s2) -> s1)); } - private Map mapCaseToStudy(List caseIds, List studyIds) { + private Map mapCaseToStudy(List caseIds, List studyIds) { Map caseToStudy = new HashMap<>(); - - for (int i =0; i < caseIds.size(); i++) { + + for (int i = 0; i < caseIds.size(); i++) { String studyId = studyIds.get(i); String caseId = caseIds.get(i); String key = generateCaseToStudyKey(studyId, caseId); caseToStudy.put(key, studyId); } - + return caseToStudy; } private String generateSampleToStudyKey(Binnable clinicalData) { return generateCaseToStudyKey(clinicalData.getStudyId(), clinicalData.getSampleId()); } - + private String generatePatientToStudyKey(Binnable clinicalData) { return generateCaseToStudyKey(clinicalData.getStudyId(), clinicalData.getPatientId()); } - + private String generateCaseToStudyKey(String studyId, String caseId) { return studyId + ":" + caseId; } - + + public SampleIdentifier buildSampleIdentifier(String studyId, String sampleId) { + SampleIdentifier sampleIdentifier = new SampleIdentifier(); + sampleIdentifier.setStudyId(studyId); + sampleIdentifier.setSampleId(sampleId); + return sampleIdentifier; + } + + public List transformSampleIdentifiersToClinicalData(List sampleIdentifiers, String attributeId, String attributeValue) { + return sampleIdentifiers + .stream() + .map(sampleIdentifier -> { + ClinicalData clinicalData = new ClinicalData(); + clinicalData.setAttrId(attributeId); + clinicalData.setAttrValue(attributeValue); + clinicalData.setSampleId(sampleIdentifier.getSampleId()); + clinicalData.setStudyId(sampleIdentifier.getStudyId()); + return clinicalData; + }).collect(Collectors.toList()); + } } diff --git a/src/main/resources/application.properties.EXAMPLE b/src/main/resources/application.properties.EXAMPLE index 673eb86ba6f..50a440c0bca 100644 --- a/src/main/resources/application.properties.EXAMPLE +++ b/src/main/resources/application.properties.EXAMPLE @@ -105,6 +105,10 @@ skin.study_view.link_text=To build your own case set, try out our enhanced Study # skin.patient_view.copy_number_table.columns.show_on_init=Gene,CNA,Annotation,Cytoband,Cohort # skin.patient_view.structural_variant_table.columns.show_on_init=Gene 1,Gene2,Status,Annotation,Variant Class,Event Info,Connection Type +# controls which column from the mutation tables, CNA tables, and SV tables is used to sort by default +# skin.results_view.tables.default_sort_column=Annotation +# skin.patient_view.tables.default_sort_column=Annotation + # setting controlling the home page ## enable this to show studies for which the user does not have permission (will appear greyed out and cannot be analyzed in study view or results view). # skin.home_page.show_unauthorized_studies=false @@ -252,8 +256,10 @@ ucsc.build=hg19 oncoprint.defaultview=patient # OncoPrint driver mutation annotations -# oncoprint.custom_driver_annotation.binary.menu_label=Custom driver annotation -# oncoprint.custom_driver_annotation.tiers.menu_label=Custom driver tiers +# oncoprint.custom_driver_annotation.binary.menu_label=Custom Driver +# oncoprint.custom_driver_annotation.binary.menu_description=Custom driver annotation +# oncoprint.custom_driver_annotation.tiers.menu_label=Custom Driver Tiers +# oncoprint.custom_driver_annotation.tiers.menu_description=Custom driver tiers # oncoprint.custom_driver_annotation.binary.default=true # oncoprint.custom_driver_annotation.tiers.default=true oncoprint.oncokb.default=true @@ -377,7 +383,7 @@ persistence.cache_type=no-cache # comparison.categorical_na_values=NA|unknown # Set StudyDownloadLinkUrl -# Allows download links within DataSets Tab (See Portal.Properties documentation for more info) +# Allows download links within DataSets Tab (See application.properties documentation for more info) # study_download_url= # download_group= @@ -391,8 +397,6 @@ logging.level.root=INFO ## Redis HTTP Session Store # Redis Session -## Comment out the line below to enable redis caching -spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration #spring.data.redis.host=localhost #spring.data.redis.port=6379 @@ -403,4 +407,21 @@ server.max-http-request-header-size=16384 ## Enable Study Help Button on Study View Page #skin.show_study_help_button=true +# Sentry Config +#sentry.dsn= +#sentry.traces-sample-rate=1.0 Probably should change for prod +#sentry.exception-resolver-order=-2147483647 + +# Swagger Configuration +#springdoc.swagger-ui.disable-swagger-default-url=true +#springdoc.swagger-ui.path=/api/swagger-ui +#springdoc.api-docs.path=/api/v2/api-docs + +# Development Configuration +spring.devtools.restart.enabled=false + +## Study Tag functionality +#enable_study_tags=true|false + # EOL - Do not delete the following lines + diff --git a/src/main/resources/db-scripts/cbioportal-er-diagram.mwb b/src/main/resources/db-scripts/cbioportal-er-diagram.mwb index 7ec61c4282e..09aafff5a6c 100644 Binary files a/src/main/resources/db-scripts/cbioportal-er-diagram.mwb and b/src/main/resources/db-scripts/cbioportal-er-diagram.mwb differ diff --git a/src/main/resources/db-scripts/cbioportal-er-diagram.pdf b/src/main/resources/db-scripts/cbioportal-er-diagram.pdf index e4d28b91d1d..98d11e9a38f 100644 Binary files a/src/main/resources/db-scripts/cbioportal-er-diagram.pdf and b/src/main/resources/db-scripts/cbioportal-er-diagram.pdf differ diff --git a/src/main/resources/db-scripts/cbioportal-er-diagram.png b/src/main/resources/db-scripts/cbioportal-er-diagram.png index db6f3ea7104..bf74798cc71 100644 Binary files a/src/main/resources/db-scripts/cbioportal-er-diagram.png and b/src/main/resources/db-scripts/cbioportal-er-diagram.png differ diff --git a/src/main/resources/dev/security/keycloak-configuration-generated.json b/src/main/resources/dev/security/keycloak-configuration-generated.json new file mode 100644 index 00000000000..1e8e9329f76 --- /dev/null +++ b/src/main/resources/dev/security/keycloak-configuration-generated.json @@ -0,0 +1,1913 @@ +{ + "id": "cbio", + "realm": "cbio", + "displayName": "cBioPortal", + "notBefore": 0, + "defaultSignatureAlgorithm": "RS256", + "revokeRefreshToken": false, + "refreshTokenMaxReuse": 0, + "accessTokenLifespan": 300, + "accessTokenLifespanForImplicitFlow": 900, + "ssoSessionIdleTimeout": 1800, + "ssoSessionMaxLifespan": 36000, + "ssoSessionIdleTimeoutRememberMe": 0, + "ssoSessionMaxLifespanRememberMe": 0, + "offlineSessionIdleTimeout": 2592000, + "offlineSessionMaxLifespanEnabled": false, + "offlineSessionMaxLifespan": 5184000, + "clientSessionIdleTimeout": 0, + "clientSessionMaxLifespan": 0, + "clientOfflineSessionIdleTimeout": 0, + "clientOfflineSessionMaxLifespan": 0, + "accessCodeLifespan": 60, + "accessCodeLifespanUserAction": 300, + "accessCodeLifespanLogin": 1800, + "actionTokenGeneratedByAdminLifespan": 43200, + "actionTokenGeneratedByUserLifespan": 300, + "oauth2DeviceCodeLifespan": 600, + "oauth2DevicePollingInterval": 5, + "enabled": true, + "sslRequired": "none", + "registrationAllowed": false, + "registrationEmailAsUsername": false, + "rememberMe": false, + "verifyEmail": false, + "loginWithEmailAllowed": false, + "duplicateEmailsAllowed": false, + "resetPasswordAllowed": false, + "editUsernameAllowed": false, + "bruteForceProtected": false, + "permanentLockout": false, + "maxFailureWaitSeconds": 900, + "minimumQuickLoginWaitSeconds": 60, + "waitIncrementSeconds": 60, + "quickLoginCheckMilliSeconds": 1000, + "maxDeltaTimeSeconds": 43200, + "failureFactor": 30, + "defaultRole": { + "id": "bb770785-c99d-4491-ac1c-6f1a571e43dc", + "name": "default-roles-cbio", + "description": "${role_default-roles}", + "composite": true, + "clientRole": false, + "containerId": "cbio" + }, + "defaultGroups": [ + "/PUBLIC_STUDIES" + ], + "requiredCredentials": [ + "password" + ], + "otpPolicyType": "totp", + "otpPolicyAlgorithm": "HmacSHA1", + "otpPolicyInitialCounter": 0, + "otpPolicyDigits": 6, + "otpPolicyLookAheadWindow": 1, + "otpPolicyPeriod": 30, + "otpSupportedApplications": [ + "FreeOTP", + "Google Authenticator" + ], + "webAuthnPolicyRpEntityName": "keycloak", + "webAuthnPolicySignatureAlgorithms": [ + "ES256" + ], + "webAuthnPolicyRpId": "", + "webAuthnPolicyAttestationConveyancePreference": "not specified", + "webAuthnPolicyAuthenticatorAttachment": "not specified", + "webAuthnPolicyRequireResidentKey": "not specified", + "webAuthnPolicyUserVerificationRequirement": "not specified", + "webAuthnPolicyCreateTimeout": 0, + "webAuthnPolicyAvoidSameAuthenticatorRegister": false, + "webAuthnPolicyAcceptableAaguids": [], + "webAuthnPolicyPasswordlessRpEntityName": "keycloak", + "webAuthnPolicyPasswordlessSignatureAlgorithms": [ + "ES256" + ], + "webAuthnPolicyPasswordlessRpId": "", + "webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified", + "webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified", + "webAuthnPolicyPasswordlessRequireResidentKey": "not specified", + "webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified", + "webAuthnPolicyPasswordlessCreateTimeout": 0, + "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false, + "webAuthnPolicyPasswordlessAcceptableAaguids": [], + "scopeMappings": [ + { + "clientScope": "offline_access", + "roles": [ + "offline_access" + ] + } + ], + "clientScopeMappings": { + "account": [ + { + "client": "account-console", + "roles": [ + "manage-account" + ] + } + ] + }, + "clients": [ + { + "id": "447cb732-9d28-411b-b712-22a7986c029e", + "clientId": "account", + "name": "${client_account}", + "rootUrl": "${authBaseUrl}", + "baseUrl": "/realms/cbio/account/", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [ + "/realms/cbio/account/*" + ], + "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, + "defaultClientScopes": [ + "web-origins", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, + { + "id": "fc7e8395-b7f3-43d3-9c07-3c7e3cacb7ee", + "clientId": "account-console", + "name": "${client_account-console}", + "rootUrl": "${authBaseUrl}", + "baseUrl": "/realms/cbio/account/", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [ + "/realms/cbio/account/*" + ], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "pkce.code.challenge.method": "S256" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "protocolMappers": [ + { + "id": "3cf582e8-7b31-448d-972b-32ce17e9527b", + "name": "audience resolve", + "protocol": "openid-connect", + "protocolMapper": "oidc-audience-resolve-mapper", + "consentRequired": false, + "config": {} + } + ], + "defaultClientScopes": [ + "web-origins", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, + { + "id": "91156b1e-4585-440c-a706-058af196d622", + "clientId": "admin-cli", + "name": "${client_admin-cli}", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "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", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, + { + "id": "83f338ca-c017-428e-818b-f497a4d0a493", + "clientId": "broker", + "name": "${client_broker}", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": true, + "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", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, + { + "id": "4b5c2aa6-bc44-458d-ac1f-1a2166520f4d", + "clientId": "cbioportal", + "adminUrl": "http://localhost:8084/saml", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [ + "http://localhost:8080/*" + ], + "webOrigins": [ + "http://localhost:8080" + ], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "saml", + "attributes": { + "saml.assertion.signature": "false", + "saml.force.post.binding": "false", + "saml_single_logout_service_url_post": "http://localhost:8080/logout/saml2/slo", + "signing.private.key": "MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDJTDNHzHv19kM4tVLOIjpR/vez4QJk70PMbghQBdCp1Er1yU8GkQRMx0QtumQB2ML1p2f63EEd7WsAPMEVYNQv6MHJDhAIDt+npWmYrGl3PrkVA3GNzZcD+GQEMZdGcECvfocOy2tB6iMOhdnFqu4L/QfFG2yJ+CpimpijvW78cJ35oYmOTnD7R9LBAJQuBlQDpOvB+I/dFeCiNKw61HQy0nMf6oe0pBy4E7bImQ0HY/soxBnzbvPUzbBvnhb2d97l3wn6ElUMrZuQSyI+OyVgBMyv9gcgV4Wq16oEuNkWFIdY2j8GeiDlqy9KJAttgLXBjGua2lRML0a+nrfF1VbBLgyzAZZP2IS/P3QYcSE2GbPWiWXjov2vF63/VnARzQhPhuLGilWp1Nxqr0HztgSiAyx0D3wqEBic0ERAQDVuHQZdjPd7RJaJ6MBnZH9mMVQOrjspIP5Sc6Z7omou26LPTjWNwmNWnfrq1sU8ADg4Uj09PWYcuWhPKxe6K9Zm4PLGXA0fR/fCVPDKaJPXIC7FGzDDdh/uSb9OURlgHwe319FCdvm1k7xD6tEfsyORjWJFoYvyT015j9LdBuO5fwt40EPCzNezqWCaimES7u3Puyg+4mbnRDh1UuouHOHVZ4jWySrrEktI0l6JkxrqdT2ilw7ICtmFx2fsjO9qso4tGwIDAQABAoICAFT7iprBRYQtl2uVgYPtB1oenkyerfgW2zSvL2s5SUKpkYv6lRZcmsgfSDVV/2qYLJaxOkC6Q/NyjD3paEqyOmKPjWBoQ3RjcyC/wLjn8Q6auGCat5H6Pcs7Tl5G4WqncWelrzcbwght5Kb481t0MlN1W5ZnYYdN8fb29YILM5P3p3oALKabjy9Gvz8kE2rq2QVA1xdo7LOVzOQuAJhFoVjjaB8NUIV+03ETQZOmqc149EvdnmcbbG1m+RnmUCN1r/C0HO4qVyWnFYnxbl9/cOP8or2WzKNmz9O0gN7Fe0DLIejtGraNUN4lSy2t0fVE5Xb05WjWy8fuHZvUPhmTW7Ap1WBGPpfjsbp+e5kx10rwWrWlKgcF7tNUUN9v0vJWKoF2Lr0+C5dphIz6LEZO7lThjh3oOXjN4jbtoZbd9tZ614dwUTPlllgQiHhNYeAK13REpX/Jx6Dgn6w5s2g+e7++4U93FMNkYjzArXAYhQd6CisFH32fr9Cc1WuUwhe6E7fABcynmMfpZhkwcCTPT+Qb1CGsMvDUdETY1J4pL+Wlgwxidd0IKyOgIu6SpQ6JEeghJzl4XOnCWlJIlO8rts7oy/0PaPWanl5rCUeeK5g32yv85bvUNJnkZ2YGBPM8c8wqsL91A+30WX1tE65JzqNI3LGDLD/WGzCYMMR1Q0/hAoIBAQD/R6bpASFPhjgDJwqjrnEhd92I5q97f+fkGqbEsVVaZQrkw2O74EyFjMWwNNG1VzYeOAAjbRkv0mXg6v6Djbuz5omkjF+qwyxXmgpYe8aJ5sU34BWVoIJsXkdCkAC49q2KsoiYT+fFw3IjlpVcIvfkV7YnVeveJ47Z9+xjrBSkKEIfZhBsd57wV+0LZ42Q/ULuPPnTlXQ77nqtBu6DusOjO1cYod5M4k0JlJwqNn39rwxCgIr5CI1UqsVJHsZz+lGQsu5ClC02V8HOTh8UjJtAcVslo+i6gLOHxB4zvDRzAXnsFIrrukqp4Bz4djoE8np/mWDtSpanoBuF84/prpTvAoIBAQDJ3ZDIBZlmTPhDUEbb6jG/AEsqeDUBgG5igLHxUg3StWgVL4cbNcRyeKD5VxMrO7pIfBm02GRqCRpmxqeOadlBgTe52oG5MIrEVIHt1KT6E1LAP7jD0ABvf3P7e9wtXlDRAsIGLIDIsb4toQFotUi6ayl07zB0+vJ1tWU+qB1ZJWWYRpDmCQG6/1vz3dBkjRPGzT79zXSxbY2beNxKYIsL1LVR0BeLd4Tbn8mLL+fxjRep4qGO1fu+w62RqQvClSUIBgZJlpEcuhRFbAL+zhqmuaq0MkcF65bHQCs/iddF9dUpNYSzUnR6N7fb9MkJZX9ww7tHLbefu+lGVTD/8mKVAoIBAQCw4JOsxGSxNj1fKdD8YqTuXKA5+CTEvHYPHcxJYtnR/UrUAPH8vkgnDMf49FANhvTvcTvfT/twoCaI9ioNOspAt07NnZm3tu3lcM0UTAbfi+9AbNpnx0Q3FAfp/d8SSZErFdMBPfRImchfEjpBEdWS+Jc0oBsC3YPkUR0QXq4ao+5U1SIyFZwhybpr+X8kY+bZLZSoXtifofiMJM5kpaZiVn5dieJ+gRqBtd+SfBlGCeDDv08LiDps3Lo/lLxKpbmYOfJOXV8KVTnq2UQ9t8LmnuRZqz1Y5E4AlwmaLSBmQzKYOg+bj4OmOqu4GCrRPLVV7g8zu0exs4T+hilD7/wvAoIBAE3KMyvRdI7GpHkUK2o9spPfIhgooIyGmIMfAvNy4l7Lh2N6oD7tFlnigG31jy5+4sdiA2n8ZZ2zCliGvzUTNySWDgpx2MGroh4MTtF+u2CfJ6lsJOBYfIJ7BA/qaCuXh98zh99nMO2mCRp+TBO0oGUuPJiSQAMkXWDc2TovALhEwATRVK9A00jjdOTiGpdVAkT+/QJDNW/WPtal2YZT8+FIQ+NWJGybTzhvN/SKLoCYFYFjE0z+yvd1YqKaGS0P2mhgIfYjrqH6Vyt1dyYH+J89Nzofkd0HL2BzKvdeP/X2yQELXarY4IfkhtadWwdi9JxY4QeJ55QHjtqKo8pN9o0CggEAWg3kw1pLAsEtRO+5w+TLMAx8JXxhbIG2ITtGHU/eCd7YO2Ax+LHd8UjjJI59QXpmytfLd6czy8bvYaAW/LtbOPYwdWGVetWMjim5KceAz64koHcBsVK1Su4i72MWagbEcwfAlZbwrIEcccZHW0/wTvwtZzllafCJhplN0+Et6vPLG00v7+x9krZOT9zGAFbt79J/kNrwZ1BRNJIl+UPM1K18AKA4xFEmClqctejNSLLubPrwC0Vdokm8tYDRBI6r+M8w6wcHW9NXYQzQ27UZKAqrtyFXJ1coQQpwHCYJi7vztacjMOLEPuKvKNSWUanv0GBYB9lnaY3wS/ncYpn8MQ==", + "saml.server.signature": "true", + "saml.signing.certificate": "MIIFazCCA1OgAwIBAgIUVMt2XXqYekaunKy/fhcJNQzJ0uQwDQYJKoZIhvcNAQELBQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTExMTkxMzUyMzFaFw0yMjExMTkxMzUyMzFaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJTDNHzHv19kM4tVLOIjpR/vez4QJk70PMbghQBdCp1Er1yU8GkQRMx0QtumQB2ML1p2f63EEd7WsAPMEVYNQv6MHJDhAIDt+npWmYrGl3PrkVA3GNzZcD+GQEMZdGcECvfocOy2tB6iMOhdnFqu4L/QfFG2yJ+CpimpijvW78cJ35oYmOTnD7R9LBAJQuBlQDpOvB+I/dFeCiNKw61HQy0nMf6oe0pBy4E7bImQ0HY/soxBnzbvPUzbBvnhb2d97l3wn6ElUMrZuQSyI+OyVgBMyv9gcgV4Wq16oEuNkWFIdY2j8GeiDlqy9KJAttgLXBjGua2lRML0a+nrfF1VbBLgyzAZZP2IS/P3QYcSE2GbPWiWXjov2vF63/VnARzQhPhuLGilWp1Nxqr0HztgSiAyx0D3wqEBic0ERAQDVuHQZdjPd7RJaJ6MBnZH9mMVQOrjspIP5Sc6Z7omou26LPTjWNwmNWnfrq1sU8ADg4Uj09PWYcuWhPKxe6K9Zm4PLGXA0fR/fCVPDKaJPXIC7FGzDDdh/uSb9OURlgHwe319FCdvm1k7xD6tEfsyORjWJFoYvyT015j9LdBuO5fwt40EPCzNezqWCaimES7u3Puyg+4mbnRDh1UuouHOHVZ4jWySrrEktI0l6JkxrqdT2ilw7ICtmFx2fsjO9qso4tGwIDAQABo1MwUTAdBgNVHQ4EFgQU0JL52xvzhG/48H01Rxac3MOgZYEwHwYDVR0jBBgwFoAU0JL52xvzhG/48H01Rxac3MOgZYEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAYYbj4v37eUTo9mtWgtZ2hHjWtdScPlZGxZanPZZpAcN8JR07ps/wow68rQMOZR9hFS6c2+izbn3HkR3OwCK9sZeuWzrLVPUBSiXxEbRkpK/pXAd/Irat+f1ylA3j3J4VyDJymqiuIBOE9kzGWpbMdyqlHdH5XG/giLEOY66p6k5QrtKDXKzfQ7BBzO1WTe1BkWp7HerEKqM7mRSA4pRT5J7UAGn4gHOU39bnOHZPhko/rFagI2iO8T3fSBL+IWx76ROoG3DUnaZmDIuMxzeEZD7G8aPWOJCP0/mnBrAQhsEUg0bcsRa6qzWFigY4oWjxOSc2aQMRSjxrVf59Geplyhh8AY0yI49uhJJc6SztwuiX9fksCm1/Z9YZeeJr/oOkBduGpX6BQbPA7N2yKg5APdn8DVIHFALijwobz+94+d6uv4+ihlQ8jBgbo1kwMZps+BAVOODgX3RpFKmqcyX9bjWaapw+XE1U8Rtt3mcgN9qchvcIqcnGZ1PfaY1ultvAzUa4TCECiYRXSOXT4iAXv+M1i2XisuThtw7dC9HMY1D/0oA/cRxwknLsuKRRGJWbUN/Ts4GMjLmvKejQOWfS+/wHS9kQdPKS3BKZYQgqli4OG1xRErykL6SRWTKJA3+VNditbHFkJuL9dGZLu0Dmaww6K1SSnYai77uTTPdOHoc=", + "saml.artifact.binding.identifier": "eY7tz0hmV0aMmBtL/oU7BOy5kUY=", + "saml.signature.algorithm": "RSA_SHA256", + "saml_force_name_id_format": "true", + "saml.client.signature": "false", + "saml.authnstatement": "true", + "saml_name_id_format": "email", + "saml_signature_canonicalization_method": "http://www.w3.org/2001/10/xml-exc-c14n#" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": -1, + "protocolMappers": [ + { + "id": "fab43918-1994-40d4-8b4c-d0e41de7d61b", + "name": "role list", + "protocol": "saml", + "protocolMapper": "saml-role-list-mapper", + "consentRequired": false, + "config": { + "single": "false", + "attribute.nameformat": "Basic", + "attribute.name": "Role" + } + }, + { + "id": "ef7aa6fb-3bbe-478b-808e-6d56d5c8c87c", + "name": "X500 email", + "protocol": "saml", + "protocolMapper": "saml-user-property-mapper", + "consentRequired": false, + "config": { + "attribute.nameformat": "Basic", + "user.attribute": "email", + "friendly.name": "email", + "attribute.name": "email" + } + } + ], + "defaultClientScopes": [], + "optionalClientScopes": [] + }, + { + "id": "f6045634-733c-43e6-9ec5-baabd518db6c", + "clientId": "cbioportal_oauth2", + "name": "cBioPortal OIDC client", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "secret": "client_secret", + "redirectUris": [ + "http://localhost:8080/*" + ], + "webOrigins": [ + "http://localhost:8080" + ], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": true, + "nodeReRegistrationTimeout": -1, + "protocolMappers": [ + { + "id": "08812f2b-f12f-4460-93d0-ca9d5fadf4b8", + "name": "cbioportal_api_audience", + "protocol": "openid-connect", + "protocolMapper": "oidc-audience-mapper", + "consentRequired": false, + "config": { + "included.client.audience": "cbioportal_api", + "id.token.claim": "false", + "access.token.claim": "true", + "userinfo.token.claim": "false" + } + } + ], + "defaultClientScopes": [ + "email" + ], + "optionalClientScopes": [ + "offline_access", + "roles" + ] + }, + { + "id": "8d317944-4523-43e9-a198-431be79edb0f", + "clientId": "realm-management", + "name": "${client_realm-management}", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": true, + "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", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, + { + "id": "0f4c7e47-9f6b-4171-8290-283f62d02701", + "clientId": "security-admin-console", + "name": "${client_security-admin-console}", + "rootUrl": "${authAdminUrl}", + "baseUrl": "/admin/cbio/console/", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [ + "/admin/cbio/console/*" + ], + "webOrigins": [ + "+" + ], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "pkce.code.challenge.method": "S256" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "protocolMappers": [ + { + "id": "831f7ad1-c369-4237-942f-88626cec64e3", + "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", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + } + ], + "clientScopes": [ + { + "id": "6624568b-9db3-46ab-9d95-8419753ad28c", + "name": "role_list", + "description": "SAML role list", + "protocol": "saml", + "attributes": { + "consent.screen.text": "${samlRoleListScopeConsentText}", + "display.on.consent.screen": "true" + }, + "protocolMappers": [ + { + "id": "564b568d-911b-442a-a490-a423d974caef", + "name": "role list", + "protocol": "saml", + "protocolMapper": "saml-role-list-mapper", + "consentRequired": false, + "config": { + "single": "false", + "attribute.nameformat": "Basic", + "attribute.name": "Role" + } + } + ] + }, + { + "id": "2c2c551a-e90f-4adc-b09a-12421ecfc1f2", + "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": "d9dbf260-7b93-4044-ba15-68bc45facc72", + "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": "f4a0ae6d-2f2d-48d4-a55e-d9860b2e348d", + "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": "efd3125c-7be3-4550-9862-3ec9039102e8", + "name": "offline_access", + "description": "OpenID Connect built-in scope: offline_access", + "protocol": "openid-connect", + "attributes": { + "consent.screen.text": "${offlineAccessScopeConsentText}", + "display.on.consent.screen": "true" + } + }, + { + "id": "2cbfef6c-ea0d-4fc0-a386-17986ce68c8f", + "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": "c362e4af-0bca-4cda-8ce8-08fbe6ed93b7", + "name": "allowed web origins", + "protocol": "openid-connect", + "protocolMapper": "oidc-allowed-origins-mapper", + "consentRequired": false, + "config": {} + } + ] + }, + { + "id": "261ac9c1-0f3e-43fb-b85c-6ef615631051", + "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": "03c75c00-2b46-4cfc-85b0-37813f4730c8", + "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": "5b81ae41-fb64-4e5e-9165-ecd74d27160c", + "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": "38806f4c-bff9-41c6-b111-36dd67953b13", + "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": "39bdb32a-43e9-4193-ab6d-73315dd1edb2", + "name": "audience resolve", + "protocol": "openid-connect", + "protocolMapper": "oidc-audience-resolve-mapper", + "consentRequired": false, + "config": {} + }, + { + "id": "4e09ee37-8e25-4335-a98b-c88945ab00b4", + "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": "dbcdd3b9-3fbb-46bb-b0eb-e924d7982c1a", + "name": "client roles", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-client-role-mapper", + "consentRequired": false, + "config": { + "multivalued": "true", + "userinfo.token.claim": "true", + "user.attribute": "foo", + "access.token.claim": "true", + "claim.name": "resource_access.${client_id}.roles", + "jsonType.label": "String" + } + } + ] + }, + { + "id": "ba043066-3611-44f3-8ce7-0d63ee7214e6", + "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": "3a55b7fa-84bd-4f68-9ed2-34359b04c3c2", + "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": "09fc3174-1c39-4a98-8727-8571d7196213", + "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": "39463f1e-621e-411a-8820-a9b83d579fc5", + "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": "c65a4612-d8e1-4588-886b-8e7946acf5a9", + "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": "78ec825f-a961-490e-8128-659d1d70c4e6", + "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": "65cae517-5bf6-4af0-90da-7ed6cff2a6a3", + "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": "4bd831ec-e2db-45b8-8d20-c2636d9b592e", + "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": "8275c531-59cd-450a-9499-53549aedda41", + "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": "aa3a327a-7039-4f67-94ae-972d5be7b1af", + "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": "97591cbb-a403-49b2-8f34-192913218437", + "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": "bedf23ca-a1fd-40a5-8acb-19bedf7da354", + "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": "40988b4c-3c7f-415c-9bf5-f4463b611fc2", + "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": "d3f3f74d-c9ab-4d0a-8ebd-51673cdbf151", + "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": "1973c75f-bc92-48a4-ac74-fb900dabe17a", + "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": "321e898f-d85c-4d8e-9900-1cf94b49fff1", + "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": "bb4b6b50-8cc9-45b3-be23-6a2671f0bcf0", + "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": "ddaf0658-e10d-4a8a-8657-16c69eaa7d1e", + "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": "17e90911-d87b-44de-9448-8e8ed92c5ae7", + "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": "a0e1d5be-5d5f-49b1-8467-9052561914e9", + "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" + } + } + ] + } + ], + "defaultDefaultClientScopes": [ + "web-origins", + "roles", + "profile", + "role_list", + "email" + ], + "defaultOptionalClientScopes": [ + "address", + "phone", + "microprofile-jwt", + "offline_access" + ], + "browserSecurityHeaders": { + "contentSecurityPolicyReportOnly": "", + "xContentTypeOptions": "nosniff", + "xRobotsTag": "none", + "xFrameOptions": "SAMEORIGIN", + "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", + "xXSSProtection": "1; mode=block", + "strictTransportSecurity": "max-age=31536000; includeSubDomains" + }, + "smtpServer": {}, + "eventsEnabled": false, + "eventsListeners": [ + "jboss-logging" + ], + "enabledEventTypes": [], + "adminEventsEnabled": false, + "adminEventsDetailsEnabled": false, + "identityProviders": [], + "identityProviderMappers": [], + "components": { + "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [ + { + "id": "889a17cb-5649-4149-8582-33076c1c3317", + "name": "Allowed Client Scopes", + "providerId": "allowed-client-templates", + "subType": "authenticated", + "subComponents": {}, + "config": { + "allow-default-scopes": [ + "true" + ] + } + }, + { + "id": "4c79fd7c-b4fe-470d-8786-f58ab99a518e", + "name": "Allowed Client Scopes", + "providerId": "allowed-client-templates", + "subType": "anonymous", + "subComponents": {}, + "config": { + "allow-default-scopes": [ + "true" + ] + } + }, + { + "id": "6fbe15a3-e5b2-4342-97cb-bde10366963c", + "name": "Allowed Protocol Mapper Types", + "providerId": "allowed-protocol-mappers", + "subType": "authenticated", + "subComponents": {}, + "config": { + "allowed-protocol-mapper-types": [ + "saml-user-attribute-mapper", + "oidc-full-name-mapper", + "oidc-usermodel-attribute-mapper", + "saml-user-property-mapper", + "oidc-address-mapper", + "oidc-sha256-pairwise-sub-mapper", + "oidc-usermodel-property-mapper", + "saml-role-list-mapper" + ] + } + }, + { + "id": "c7824d6e-b0e6-49cc-bff6-68b2f011a542", + "name": "Trusted Hosts", + "providerId": "trusted-hosts", + "subType": "anonymous", + "subComponents": {}, + "config": { + "host-sending-registration-request-must-match": [ + "true" + ], + "client-uris-must-match": [ + "true" + ] + } + }, + { + "id": "196f1f2a-bc8b-425a-89d9-86cdfb20fcfd", + "name": "Max Clients Limit", + "providerId": "max-clients", + "subType": "anonymous", + "subComponents": {}, + "config": { + "max-clients": [ + "200" + ] + } + }, + { + "id": "9e90ed2b-a6a2-42fd-988e-58ea0ddeb63d", + "name": "Allowed Protocol Mapper Types", + "providerId": "allowed-protocol-mappers", + "subType": "anonymous", + "subComponents": {}, + "config": { + "allowed-protocol-mapper-types": [ + "oidc-full-name-mapper", + "saml-role-list-mapper", + "oidc-sha256-pairwise-sub-mapper", + "saml-user-property-mapper", + "saml-user-attribute-mapper", + "oidc-usermodel-attribute-mapper", + "oidc-address-mapper", + "oidc-usermodel-property-mapper" + ] + } + }, + { + "id": "2ce4cd15-6601-482f-81e2-c7c5621e06f9", + "name": "Full Scope Disabled", + "providerId": "scope", + "subType": "anonymous", + "subComponents": {}, + "config": {} + }, + { + "id": "1375acc0-7aa9-4b3f-a0c0-a40c290e3f73", + "name": "Consent Required", + "providerId": "consent-required", + "subType": "anonymous", + "subComponents": {}, + "config": {} + } + ], + "org.keycloak.keys.KeyProvider": [ + { + "id": "53680454-4c6c-4486-861f-e5e74befe868", + "name": "hmac-generated", + "providerId": "hmac-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ], + "algorithm": [ + "HS256" + ] + } + }, + { + "id": "e684156b-42ad-4576-b047-e1cb35f3fc05", + "name": "rsa-generated", + "providerId": "rsa-generated", + "subComponents": {}, + "config": { + "keyUse": [ + "sig" + ], + "priority": [ + "100" + ] + } + }, + { + "id": "014ff5f5-de31-48d2-952f-1445e8da62e1", + "name": "aes-generated", + "providerId": "aes-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ] + } + }, + { + "id": "557a3a1f-1036-4fd5-8656-35ef6c482f50", + "name": "rsa-enc-generated", + "providerId": "rsa-generated", + "subComponents": {}, + "config": { + "keyUse": [ + "enc" + ], + "priority": [ + "100" + ] + } + } + ] + }, + "internationalizationEnabled": false, + "supportedLocales": [], + "authenticationFlows": [ + { + "id": "d09f86a8-3eb7-4b08-8c02-36a56f6a2a2c", + "alias": "Account verification options", + "description": "Method with which to verity the existing account", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "idp-email-verification", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "ALTERNATIVE", + "priority": 20, + "flowAlias": "Verify Existing Account by Re-authentication", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "3801ca86-b775-4af6-a7cc-a5125e1a67b1", + "alias": "Authentication Options", + "description": "Authentication options.", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "basic-auth", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "basic-auth-otp", + "authenticatorFlow": false, + "requirement": "DISABLED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "auth-spnego", + "authenticatorFlow": false, + "requirement": "DISABLED", + "priority": 30, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "2f229147-9906-45ed-bbf9-a7cb9e0a6650", + "alias": "Browser - Conditional OTP", + "description": "Flow to determine if the OTP is required for the authentication", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "auth-otp-form", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "50e71410-d2fd-4b68-8972-c9e49ecee7c0", + "alias": "Direct Grant - Conditional OTP", + "description": "Flow to determine if the OTP is required for the authentication", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "direct-grant-validate-otp", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "7f4cfad2-bd68-4ac4-8d8d-d22ed18214fe", + "alias": "First broker login - Conditional OTP", + "description": "Flow to determine if the OTP is required for the authentication", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "auth-otp-form", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "dbbb7d22-5602-4ce4-aa53-40bf6391b50c", + "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", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "REQUIRED", + "priority": 20, + "flowAlias": "Account verification options", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "6e414865-f4f0-4295-83f4-ca5edce533f0", + "alias": "Reset - Conditional OTP", + "description": "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "reset-otp", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "85f5eeb7-78e7-4ef4-962e-c23fba388dd6", + "alias": "User creation or linking", + "description": "Flow for the existing/non-existing user alternatives", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticatorConfig": "create unique user config", + "authenticator": "idp-create-user-if-unique", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "ALTERNATIVE", + "priority": 20, + "flowAlias": "Handle Existing Account", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "4e9649e7-a343-4f82-8293-c020c26e14d5", + "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", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 20, + "flowAlias": "First broker login - Conditional OTP", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "c4297697-2daf-4b81-9340-2244f5f6f4d1", + "alias": "browser", + "description": "browser based authentication", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "auth-cookie", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "auth-spnego", + "authenticatorFlow": false, + "requirement": "DISABLED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "identity-provider-redirector", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 25, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "ALTERNATIVE", + "priority": 30, + "flowAlias": "forms", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "c9f07e45-6e38-45e8-938d-7314d2596b63", + "alias": "clients", + "description": "Base authentication for clients", + "providerId": "client-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "client-secret", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "client-jwt", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "client-secret-jwt", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 30, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "client-x509", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 40, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "55cf854b-47fb-4b05-9eef-6840f92fee79", + "alias": "direct grant", + "description": "OpenID Connect Resource Owner Grant", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "direct-grant-validate-username", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "direct-grant-validate-password", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 30, + "flowAlias": "Direct Grant - Conditional OTP", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "14fe6c33-9d93-4c95-988b-d5e0a1d2fe4b", + "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", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "bce646e3-ebd1-4d8e-8703-ea91621f3550", + "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", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "REQUIRED", + "priority": 20, + "flowAlias": "User creation or linking", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "fae27840-4d5e-4a27-a1b5-1b44414b776f", + "alias": "forms", + "description": "Username, password, otp and other auth forms.", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "auth-username-password-form", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 20, + "flowAlias": "Browser - Conditional OTP", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "d391fa3e-0975-4db4-8ab1-d2f8348ed395", + "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", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "REQUIRED", + "priority": 20, + "flowAlias": "Authentication Options", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "380a97f7-a283-4716-88e9-c21e5efd3867", + "alias": "registration", + "description": "registration flow", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "registration-page-form", + "authenticatorFlow": true, + "requirement": "REQUIRED", + "priority": 10, + "flowAlias": "registration form", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "0a5ea500-02e9-490a-9cb4-b7d030ed3372", + "alias": "registration form", + "description": "registration form", + "providerId": "form-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "registration-user-creation", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "registration-profile-action", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 40, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "registration-password-action", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 50, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "registration-recaptcha-action", + "authenticatorFlow": false, + "requirement": "DISABLED", + "priority": 60, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "1dace197-f541-4109-9c50-aa172ce6ac14", + "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", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "reset-credential-email", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "reset-password", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 30, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 40, + "flowAlias": "Reset - Conditional OTP", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "744c784a-2933-4ea7-9c98-b89b37cdfafc", + "alias": "saml ecp", + "description": "SAML ECP Profile Authentication Flow", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "http-basic-authenticator", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + } + ], + "authenticatorConfig": [ + { + "id": "0231eced-f393-479f-9d3e-0deb23879cd2", + "alias": "create unique user config", + "config": { + "require.password.update.after.registration": "false" + } + }, + { + "id": "24782868-8536-44aa-a808-c8af37085ce5", + "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": {} + }, + { + "alias": "delete_account", + "name": "Delete Account", + "providerId": "delete_account", + "enabled": false, + "defaultAction": false, + "priority": 60, + "config": {} + }, + { + "alias": "update_user_locale", + "name": "Update User Locale", + "providerId": "update_user_locale", + "enabled": true, + "defaultAction": false, + "priority": 1000, + "config": {} + } + ], + "browserFlow": "browser", + "registrationFlow": "registration", + "directGrantFlow": "direct grant", + "resetCredentialsFlow": "reset credentials", + "clientAuthenticationFlow": "clients", + "dockerAuthenticationFlow": "docker auth", + "attributes": { + "cibaBackchannelTokenDeliveryMode": "poll", + "cibaExpiresIn": "120", + "cibaAuthRequestedUserHint": "login_hint", + "oauth2DeviceCodeLifespan": "600", + "oauth2DevicePollingInterval": "5", + "parRequestUriLifespan": "60", + "cibaInterval": "5" + }, + "keycloakVersion": "15.0.2", + "userManagedAccessAllowed": false, + "clientProfiles": { + "profiles": [] + }, + "clientPolicies": { + "policies": [] + }, + "users": [ + { + "username": "testuser", + "enabled": true, + "email": "testuser@thehyve.nl", + "credentials": [ + { + "type": "password", + "value": "P@ssword1" + } + ], + "realmRoles": [ + "offline_access" + ], + "groups": [ + "/PUBLIC_STUDIES" + ] + } + ], + "roles": { + "client": { + "cbioportal": [ + { + "name": "study_tcga_pub" + } + ] + } + }, + "groups": [ + { + "name": "PUBLIC_STUDIES", + "clientRoles": { + "cbioportal": [ + "study_tcga_pub" + ] + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/dev/security/signing-cert.pem b/src/main/resources/dev/security/signing-cert.pem new file mode 100644 index 00000000000..01883dcafef --- /dev/null +++ b/src/main/resources/dev/security/signing-cert.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIUVMt2XXqYekaunKy/fhcJNQzJ0uQwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTExMTkxMzUyMzFaFw0yMjEx +MTkxMzUyMzFaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDJTDNHzHv19kM4tVLOIjpR/vez4QJk70PMbghQBdCp +1Er1yU8GkQRMx0QtumQB2ML1p2f63EEd7WsAPMEVYNQv6MHJDhAIDt+npWmYrGl3 +PrkVA3GNzZcD+GQEMZdGcECvfocOy2tB6iMOhdnFqu4L/QfFG2yJ+CpimpijvW78 +cJ35oYmOTnD7R9LBAJQuBlQDpOvB+I/dFeCiNKw61HQy0nMf6oe0pBy4E7bImQ0H +Y/soxBnzbvPUzbBvnhb2d97l3wn6ElUMrZuQSyI+OyVgBMyv9gcgV4Wq16oEuNkW +FIdY2j8GeiDlqy9KJAttgLXBjGua2lRML0a+nrfF1VbBLgyzAZZP2IS/P3QYcSE2 +GbPWiWXjov2vF63/VnARzQhPhuLGilWp1Nxqr0HztgSiAyx0D3wqEBic0ERAQDVu +HQZdjPd7RJaJ6MBnZH9mMVQOrjspIP5Sc6Z7omou26LPTjWNwmNWnfrq1sU8ADg4 +Uj09PWYcuWhPKxe6K9Zm4PLGXA0fR/fCVPDKaJPXIC7FGzDDdh/uSb9OURlgHwe3 +19FCdvm1k7xD6tEfsyORjWJFoYvyT015j9LdBuO5fwt40EPCzNezqWCaimES7u3P +uyg+4mbnRDh1UuouHOHVZ4jWySrrEktI0l6JkxrqdT2ilw7ICtmFx2fsjO9qso4t +GwIDAQABo1MwUTAdBgNVHQ4EFgQU0JL52xvzhG/48H01Rxac3MOgZYEwHwYDVR0j +BBgwFoAU0JL52xvzhG/48H01Rxac3MOgZYEwDwYDVR0TAQH/BAUwAwEB/zANBgkq +hkiG9w0BAQsFAAOCAgEAYYbj4v37eUTo9mtWgtZ2hHjWtdScPlZGxZanPZZpAcN8 +JR07ps/wow68rQMOZR9hFS6c2+izbn3HkR3OwCK9sZeuWzrLVPUBSiXxEbRkpK/p +XAd/Irat+f1ylA3j3J4VyDJymqiuIBOE9kzGWpbMdyqlHdH5XG/giLEOY66p6k5Q +rtKDXKzfQ7BBzO1WTe1BkWp7HerEKqM7mRSA4pRT5J7UAGn4gHOU39bnOHZPhko/ +rFagI2iO8T3fSBL+IWx76ROoG3DUnaZmDIuMxzeEZD7G8aPWOJCP0/mnBrAQhsEU +g0bcsRa6qzWFigY4oWjxOSc2aQMRSjxrVf59Geplyhh8AY0yI49uhJJc6SztwuiX +9fksCm1/Z9YZeeJr/oOkBduGpX6BQbPA7N2yKg5APdn8DVIHFALijwobz+94+d6u +v4+ihlQ8jBgbo1kwMZps+BAVOODgX3RpFKmqcyX9bjWaapw+XE1U8Rtt3mcgN9qc +hvcIqcnGZ1PfaY1ultvAzUa4TCECiYRXSOXT4iAXv+M1i2XisuThtw7dC9HMY1D/ +0oA/cRxwknLsuKRRGJWbUN/Ts4GMjLmvKejQOWfS+/wHS9kQdPKS3BKZYQgqli4O +G1xRErykL6SRWTKJA3+VNditbHFkJuL9dGZLu0Dmaww6K1SSnYai77uTTPdOHoc= +-----END CERTIFICATE----- diff --git a/src/main/resources/dev/security/signing-key.pem b/src/main/resources/dev/security/signing-key.pem new file mode 100644 index 00000000000..ee46d3f2156 --- /dev/null +++ b/src/main/resources/dev/security/signing-key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDJTDNHzHv19kM4 +tVLOIjpR/vez4QJk70PMbghQBdCp1Er1yU8GkQRMx0QtumQB2ML1p2f63EEd7WsA +PMEVYNQv6MHJDhAIDt+npWmYrGl3PrkVA3GNzZcD+GQEMZdGcECvfocOy2tB6iMO +hdnFqu4L/QfFG2yJ+CpimpijvW78cJ35oYmOTnD7R9LBAJQuBlQDpOvB+I/dFeCi +NKw61HQy0nMf6oe0pBy4E7bImQ0HY/soxBnzbvPUzbBvnhb2d97l3wn6ElUMrZuQ +SyI+OyVgBMyv9gcgV4Wq16oEuNkWFIdY2j8GeiDlqy9KJAttgLXBjGua2lRML0a+ +nrfF1VbBLgyzAZZP2IS/P3QYcSE2GbPWiWXjov2vF63/VnARzQhPhuLGilWp1Nxq +r0HztgSiAyx0D3wqEBic0ERAQDVuHQZdjPd7RJaJ6MBnZH9mMVQOrjspIP5Sc6Z7 +omou26LPTjWNwmNWnfrq1sU8ADg4Uj09PWYcuWhPKxe6K9Zm4PLGXA0fR/fCVPDK +aJPXIC7FGzDDdh/uSb9OURlgHwe319FCdvm1k7xD6tEfsyORjWJFoYvyT015j9Ld +BuO5fwt40EPCzNezqWCaimES7u3Puyg+4mbnRDh1UuouHOHVZ4jWySrrEktI0l6J +kxrqdT2ilw7ICtmFx2fsjO9qso4tGwIDAQABAoICAFT7iprBRYQtl2uVgYPtB1oe +nkyerfgW2zSvL2s5SUKpkYv6lRZcmsgfSDVV/2qYLJaxOkC6Q/NyjD3paEqyOmKP +jWBoQ3RjcyC/wLjn8Q6auGCat5H6Pcs7Tl5G4WqncWelrzcbwght5Kb481t0MlN1 +W5ZnYYdN8fb29YILM5P3p3oALKabjy9Gvz8kE2rq2QVA1xdo7LOVzOQuAJhFoVjj +aB8NUIV+03ETQZOmqc149EvdnmcbbG1m+RnmUCN1r/C0HO4qVyWnFYnxbl9/cOP8 +or2WzKNmz9O0gN7Fe0DLIejtGraNUN4lSy2t0fVE5Xb05WjWy8fuHZvUPhmTW7Ap +1WBGPpfjsbp+e5kx10rwWrWlKgcF7tNUUN9v0vJWKoF2Lr0+C5dphIz6LEZO7lTh +jh3oOXjN4jbtoZbd9tZ614dwUTPlllgQiHhNYeAK13REpX/Jx6Dgn6w5s2g+e7++ +4U93FMNkYjzArXAYhQd6CisFH32fr9Cc1WuUwhe6E7fABcynmMfpZhkwcCTPT+Qb +1CGsMvDUdETY1J4pL+Wlgwxidd0IKyOgIu6SpQ6JEeghJzl4XOnCWlJIlO8rts7o +y/0PaPWanl5rCUeeK5g32yv85bvUNJnkZ2YGBPM8c8wqsL91A+30WX1tE65JzqNI +3LGDLD/WGzCYMMR1Q0/hAoIBAQD/R6bpASFPhjgDJwqjrnEhd92I5q97f+fkGqbE +sVVaZQrkw2O74EyFjMWwNNG1VzYeOAAjbRkv0mXg6v6Djbuz5omkjF+qwyxXmgpY +e8aJ5sU34BWVoIJsXkdCkAC49q2KsoiYT+fFw3IjlpVcIvfkV7YnVeveJ47Z9+xj +rBSkKEIfZhBsd57wV+0LZ42Q/ULuPPnTlXQ77nqtBu6DusOjO1cYod5M4k0JlJwq +Nn39rwxCgIr5CI1UqsVJHsZz+lGQsu5ClC02V8HOTh8UjJtAcVslo+i6gLOHxB4z +vDRzAXnsFIrrukqp4Bz4djoE8np/mWDtSpanoBuF84/prpTvAoIBAQDJ3ZDIBZlm +TPhDUEbb6jG/AEsqeDUBgG5igLHxUg3StWgVL4cbNcRyeKD5VxMrO7pIfBm02GRq +CRpmxqeOadlBgTe52oG5MIrEVIHt1KT6E1LAP7jD0ABvf3P7e9wtXlDRAsIGLIDI +sb4toQFotUi6ayl07zB0+vJ1tWU+qB1ZJWWYRpDmCQG6/1vz3dBkjRPGzT79zXSx +bY2beNxKYIsL1LVR0BeLd4Tbn8mLL+fxjRep4qGO1fu+w62RqQvClSUIBgZJlpEc +uhRFbAL+zhqmuaq0MkcF65bHQCs/iddF9dUpNYSzUnR6N7fb9MkJZX9ww7tHLbef +u+lGVTD/8mKVAoIBAQCw4JOsxGSxNj1fKdD8YqTuXKA5+CTEvHYPHcxJYtnR/UrU +APH8vkgnDMf49FANhvTvcTvfT/twoCaI9ioNOspAt07NnZm3tu3lcM0UTAbfi+9A +bNpnx0Q3FAfp/d8SSZErFdMBPfRImchfEjpBEdWS+Jc0oBsC3YPkUR0QXq4ao+5U +1SIyFZwhybpr+X8kY+bZLZSoXtifofiMJM5kpaZiVn5dieJ+gRqBtd+SfBlGCeDD +v08LiDps3Lo/lLxKpbmYOfJOXV8KVTnq2UQ9t8LmnuRZqz1Y5E4AlwmaLSBmQzKY +Og+bj4OmOqu4GCrRPLVV7g8zu0exs4T+hilD7/wvAoIBAE3KMyvRdI7GpHkUK2o9 +spPfIhgooIyGmIMfAvNy4l7Lh2N6oD7tFlnigG31jy5+4sdiA2n8ZZ2zCliGvzUT +NySWDgpx2MGroh4MTtF+u2CfJ6lsJOBYfIJ7BA/qaCuXh98zh99nMO2mCRp+TBO0 +oGUuPJiSQAMkXWDc2TovALhEwATRVK9A00jjdOTiGpdVAkT+/QJDNW/WPtal2YZT +8+FIQ+NWJGybTzhvN/SKLoCYFYFjE0z+yvd1YqKaGS0P2mhgIfYjrqH6Vyt1dyYH ++J89Nzofkd0HL2BzKvdeP/X2yQELXarY4IfkhtadWwdi9JxY4QeJ55QHjtqKo8pN +9o0CggEAWg3kw1pLAsEtRO+5w+TLMAx8JXxhbIG2ITtGHU/eCd7YO2Ax+LHd8Ujj +JI59QXpmytfLd6czy8bvYaAW/LtbOPYwdWGVetWMjim5KceAz64koHcBsVK1Su4i +72MWagbEcwfAlZbwrIEcccZHW0/wTvwtZzllafCJhplN0+Et6vPLG00v7+x9krZO +T9zGAFbt79J/kNrwZ1BRNJIl+UPM1K18AKA4xFEmClqctejNSLLubPrwC0Vdokm8 +tYDRBI6r+M8w6wcHW9NXYQzQ27UZKAqrtyFXJ1coQQpwHCYJi7vztacjMOLEPuKv +KNSWUanv0GBYB9lnaY3wS/ncYpn8MQ== +-----END PRIVATE KEY----- diff --git a/src/main/resources/legacy-api.json b/src/main/resources/legacy-api.json new file mode 100644 index 00000000000..2239a91b458 --- /dev/null +++ b/src/main/resources/legacy-api.json @@ -0,0 +1 @@ +{"swagger":"2.0","info":{"description":"A web service for supplying JSON formatted data to cBioPortal clients. Please note that this API is currently in beta and subject to change.","version":"1.0 (beta). Backwards compatibility will be maintained (after 1.0 release)","title":"cBioPortal web Public API [Beta]","contact":{"name":"cBioPortal","url":"https://www.cbioportal.org","email":"cbioportal@googlegroups.com"},"license":{"name":"License","url":"https://github.com/cBioPortal/cbioportal/blob/master/LICENSE"}},"host":"www.cbioportal.org","basePath":"/api","tags":[{"name":"Cancer Types"},{"name":"Studies"},{"name":"Patients"},{"name":"Samples"},{"name":"Sample Lists"},{"name":"Clinical Attributes"},{"name":"Clinical Data"},{"name":"Molecular Data"},{"name":"Molecular Profiles"},{"name":"Mutations"},{"name":"Discrete Copy Number Alterations"},{"name":"Copy Number Segments"},{"name":"Genes"},{"name":"Gene Panels"},{"name":"Generic Assays"},{"name":"Generic Assay Data"},{"name":"Info"},{"name":"Gene Panel Data","description":" "},{"name":"Server running status","description":"This end point does not require authentication"},{"name":"Treatments","description":" "}],"paths":{"/cancer-types":{"get":{"tags":["Cancer Types"],"summary":"Get all cancer types","operationId":"getAllCancerTypesUsingGET","produces":["application/json"],"parameters":[{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["cancerTypeId","dedicatedColor","name","parent","shortName"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/TypeOfCancer"}}}}}},"/cancer-types/{cancerTypeId}":{"get":{"tags":["Cancer Types"],"summary":"Get a cancer type","operationId":"getCancerTypeUsingGET","produces":["application/json"],"parameters":[{"name":"cancerTypeId","in":"path","description":"Cancer Type ID e.g. acc","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/TypeOfCancer"}}}}},"/clinical-attributes":{"get":{"tags":["Clinical Attributes"],"summary":"Get all clinical attributes","operationId":"getAllClinicalAttributesUsingGET","produces":["application/json"],"parameters":[{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["clinicalAttributeId","datatype","description","displayName","patientAttribute","priority","studyId"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/ClinicalAttribute"}}}}}},"/clinical-attributes/fetch":{"post":{"tags":["Clinical Attributes"],"summary":"Fetch clinical attributes","operationId":"fetchClinicalAttributesUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"in":"body","name":"studyIds","description":"List of Study IDs","required":true,"schema":{"type":"array","items":{"type":"string"}}}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/ClinicalAttribute"}}}}}},"/clinical-data/fetch":{"post":{"tags":["Clinical Data"],"summary":"Fetch clinical data by patient IDs or sample IDs (all studies)","operationId":"fetchClinicalDataUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"in":"body","name":"clinicalDataMultiStudyFilter","description":"List of patient or sample identifiers and attribute IDs","required":true,"schema":{"$ref":"#/definitions/ClinicalDataMultiStudyFilter"}},{"name":"clinicalDataType","in":"query","description":"Type of the clinical data","required":false,"type":"string","default":"SAMPLE","enum":["PATIENT","SAMPLE"]},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/ClinicalData"}}}}}},"/copy-number-segments/fetch":{"post":{"tags":["Copy Number Segments"],"summary":"Fetch copy number segments by sample ID","operationId":"fetchCopyNumberSegmentsUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"name":"chromosome","in":"query","description":"Chromosome","required":false,"type":"string"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"in":"body","name":"sampleIdentifiers","description":"List of sample identifiers","required":true,"schema":{"type":"array","items":{"$ref":"#/definitions/SampleIdentifier"}}}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/CopyNumberSeg"}}}}}},"/gene-panel-data/fetch":{"post":{"tags":["Gene Panel Data"],"summary":"Fetch gene panel data","operationId":"fetchGenePanelDataInMultipleMolecularProfilesUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"in":"body","name":"genePanelDataMultipleStudyFilter","description":"Gene panel data filter object","required":true,"schema":{"$ref":"#/definitions/GenePanelDataMultipleStudyFilter"}}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/GenePanelData"}}}}}},"/gene-panels":{"get":{"tags":["Gene Panels"],"summary":"Get all gene panels","operationId":"getAllGenePanelsUsingGET","produces":["application/json"],"parameters":[{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["description","genePanelId"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/GenePanel"}}}}}},"/gene-panels/fetch":{"post":{"tags":["Gene Panels"],"summary":"Get gene panel","operationId":"fetchGenePanelsUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"in":"body","name":"genePanelIds","description":"List of Gene Panel IDs","required":true,"schema":{"type":"array","items":{"type":"string"}}},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/GenePanel"}}}}}},"/gene-panels/{genePanelId}":{"get":{"tags":["Gene Panels"],"summary":"Get gene panel","operationId":"getGenePanelUsingGET","produces":["application/json"],"parameters":[{"name":"genePanelId","in":"path","description":"Gene Panel ID e.g. NSCLC_UNITO_2016_PANEL","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/GenePanel"}}}}},"/generic-assay-data/{molecularProfileId}/generic-assay/{genericAssayStableId}":{"get":{"tags":["Generic Assay Data"],"summary":"Get generic_assay_data in a molecular profile","operationId":"getGenericAssayDataInMolecularProfileUsingGET","produces":["application/json"],"parameters":[{"name":"genericAssayStableId","in":"path","description":"Generic Assay stable ID","required":true,"type":"string"},{"name":"molecularProfileId","in":"path","description":"Molecular Profile ID","required":true,"type":"string"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/GenericAssayData"}}}}}},"/generic-assay-meta/generic-assay/{genericAssayStableId}":{"get":{"tags":["Generic Assays"],"summary":"Fetch meta data for generic-assay by ID","operationId":"getGenericAssayMeta_gaUsingGET","produces":["application/json"],"parameters":[{"name":"genericAssayStableId","in":"path","description":"Generic Assay stable ID","required":true,"type":"string"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/GenericAssayMeta"}}}}}},"/generic-assay-meta/{molecularProfileId}":{"get":{"tags":["Generic Assays"],"summary":"Fetch meta data for generic-assay by ID","operationId":"getGenericAssayMetaUsingGET","produces":["application/json"],"parameters":[{"name":"molecularProfileId","in":"path","description":"Molecular Profile ID","required":true,"type":"string"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/GenericAssayMeta"}}}}}},"/generic_assay_data/fetch":{"post":{"tags":["Generic Assay Data"],"summary":"Fetch generic_assay_data","operationId":"fetchGenericAssayDataInMultipleMolecularProfilesUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"in":"body","name":"genericAssayDataMultipleStudyFilter","description":"List of Molecular Profile ID and Sample ID pairs or List of MolecularProfile IDs and Generic Assay IDs","required":true,"schema":{"$ref":"#/definitions/GenericAssayDataMultipleStudyFilter"}},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/GenericAssayData"}}}}}},"/generic_assay_data/{molecularProfileId}/fetch":{"post":{"tags":["Generic Assay Data"],"summary":"fetch generic_assay_data in a molecular profile","operationId":"fetchGenericAssayDataInMolecularProfileUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"in":"body","name":"genericAssayDataFilter","description":"List of Sample IDs/Sample List ID and Generic Assay IDs","required":true,"schema":{"$ref":"#/definitions/GenericAssayFilter"}},{"name":"molecularProfileId","in":"path","description":"Molecular Profile ID","required":true,"type":"string"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/GenericAssayData"}}}}}},"/generic_assay_meta/fetch":{"post":{"tags":["Generic Assays"],"summary":"Fetch meta data for generic-assay by ID","operationId":"fetchGenericAssayMetaUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"in":"body","name":"genericAssayMetaFilter","description":"List of Molecular Profile ID or List of Stable ID","required":true,"schema":{"$ref":"#/definitions/GenericAssayMetaFilter"}},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/GenericAssayMeta"}}}}}},"/genes":{"get":{"tags":["Genes"],"summary":"Get all genes","operationId":"getAllGenesUsingGET","produces":["application/json"],"parameters":[{"name":"alias","in":"query","description":"Alias of the gene","required":false,"type":"string"},{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"keyword","in":"query","description":"Search keyword that applies to hugo gene symbol of the genes","required":false,"type":"string"},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["cytoband","entrezGeneId","hugoGeneSymbol","length","type"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/Gene"}}}}}},"/genes/fetch":{"post":{"tags":["Genes"],"summary":"Fetch genes by ID","operationId":"fetchGenesUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"in":"body","name":"geneIds","description":"List of Entrez Gene IDs or Hugo Gene Symbols","required":true,"schema":{"type":"array","items":{"type":"string"}}},{"name":"geneIdType","in":"query","description":"Type of gene ID","required":false,"type":"string","default":"ENTREZ_GENE_ID","enum":["ENTREZ_GENE_ID","HUGO_GENE_SYMBOL"]},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/Gene"}}}}}},"/genes/{geneId}":{"get":{"tags":["Genes"],"summary":"Get a gene","operationId":"getGeneUsingGET","produces":["application/json"],"parameters":[{"name":"geneId","in":"path","description":"Entrez Gene ID or Hugo Gene Symbol e.g. 1 or A1BG","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/Gene"}}}}},"/genes/{geneId}/aliases":{"get":{"tags":["Genes"],"summary":"Get aliases of a gene","operationId":"getAliasesOfGeneUsingGET","produces":["application/json"],"parameters":[{"name":"geneId","in":"path","description":"Entrez Gene ID or Hugo Gene Symbol e.g. 1 or A1BG","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"type":"string"}}}}}},"/health":{"get":{"tags":["Server running status"],"summary":"Get the running status of the server","operationId":"getServerStatusUsingGET","produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/ServerStatusMessage"}}}}},"/info":{"get":{"tags":["Info"],"summary":"Get information about the running instance","operationId":"getInfoUsingGET","produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/Info"}}}}},"/molecular-data/fetch":{"post":{"tags":["Molecular Data"],"summary":"Fetch molecular data","operationId":"fetchMolecularDataInMultipleMolecularProfilesUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"in":"body","name":"molecularDataMultipleStudyFilter","description":"List of Molecular Profile ID and Sample ID pairs or List of MolecularProfile IDs and Entrez Gene IDs","required":true,"schema":{"$ref":"#/definitions/MolecularDataMultipleStudyFilter"}},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/NumericGeneMolecularData"}}}}}},"/molecular-profiles":{"get":{"tags":["Molecular Profiles"],"summary":"Get all molecular profiles","operationId":"getAllMolecularProfilesUsingGET","produces":["application/json"],"parameters":[{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["datatype","description","molecularAlterationType","molecularProfileId","name","showProfileInAnalysisTab"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/MolecularProfile"}}}}}},"/molecular-profiles/fetch":{"post":{"tags":["Molecular Profiles"],"summary":"Fetch molecular profiles","operationId":"fetchMolecularProfilesUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"in":"body","name":"molecularProfileFilter","description":"List of Molecular Profile IDs or List of Study IDs","required":true,"schema":{"$ref":"#/definitions/MolecularProfileFilter"}},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/MolecularProfile"}}}}}},"/molecular-profiles/{molecularProfileId}":{"get":{"tags":["Molecular Profiles"],"summary":"Get molecular profile","operationId":"getMolecularProfileUsingGET","produces":["application/json"],"parameters":[{"name":"molecularProfileId","in":"path","description":"Molecular Profile ID e.g. acc_tcga_mutations","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/MolecularProfile"}}}}},"/molecular-profiles/{molecularProfileId}/discrete-copy-number":{"get":{"tags":["Discrete Copy Number Alterations"],"summary":"Get discrete copy number alterations in a molecular profile","operationId":"getDiscreteCopyNumbersInMolecularProfileUsingGET","produces":["application/json"],"parameters":[{"name":"discreteCopyNumberEventType","in":"query","description":"Type of the copy number event","required":false,"type":"string","default":"HOMDEL_AND_AMP","enum":["ALL","AMP","DIPLOID","GAIN","HETLOSS","HOMDEL","HOMDEL_AND_AMP"]},{"name":"molecularProfileId","in":"path","description":"Molecular Profile ID e.g. acc_tcga_gistic","required":true,"type":"string"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sampleListId","in":"query","description":"Sample List ID e.g. acc_tcga_all","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/DiscreteCopyNumberData"}}}}}},"/molecular-profiles/{molecularProfileId}/discrete-copy-number/fetch":{"post":{"tags":["Discrete Copy Number Alterations"],"summary":"Fetch discrete copy number alterations in a molecular profile by sample ID","operationId":"fetchDiscreteCopyNumbersInMolecularProfileUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"name":"discreteCopyNumberEventType","in":"query","description":"Type of the copy number event","required":false,"type":"string","default":"HOMDEL_AND_AMP","enum":["ALL","AMP","DIPLOID","GAIN","HETLOSS","HOMDEL","HOMDEL_AND_AMP"]},{"in":"body","name":"discreteCopyNumberFilter","description":"List of Sample IDs/Sample List ID and Entrez Gene IDs","required":true,"schema":{"$ref":"#/definitions/DiscreteCopyNumberFilter"}},{"name":"molecularProfileId","in":"path","description":"Molecular Profile ID e.g. acc_tcga_gistic","required":true,"type":"string"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/DiscreteCopyNumberData"}}}}}},"/molecular-profiles/{molecularProfileId}/gene-panel-data/fetch":{"post":{"tags":["Gene Panel Data"],"summary":"Get gene panel data","operationId":"getGenePanelDataUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"in":"body","name":"genePanelDataFilter","description":"List of Sample IDs/Sample List ID and Entrez Gene IDs","required":true,"schema":{"$ref":"#/definitions/GenePanelDataFilter"}},{"name":"molecularProfileId","in":"path","description":"Molecular Profile ID e.g. nsclc_unito_2016_mutations","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/GenePanelData"}}}}}},"/molecular-profiles/{molecularProfileId}/molecular-data":{"get":{"tags":["Molecular Data"],"summary":"Get all molecular data in a molecular profile","operationId":"getAllMolecularDataInMolecularProfileUsingGET","produces":["application/json"],"parameters":[{"name":"entrezGeneId","in":"query","description":"Entrez Gene ID e.g. 1","required":true,"type":"integer","format":"int32"},{"name":"molecularProfileId","in":"path","description":"Molecular Profile ID e.g. acc_tcga_rna_seq_v2_mrna","required":true,"type":"string"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sampleListId","in":"query","description":"Sample List ID e.g. acc_tcga_all","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/NumericGeneMolecularData"}}}}}},"/molecular-profiles/{molecularProfileId}/molecular-data/fetch":{"post":{"tags":["Molecular Data"],"summary":"Fetch molecular data in a molecular profile","operationId":"fetchAllMolecularDataInMolecularProfileUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"in":"body","name":"molecularDataFilter","description":"List of Sample IDs/Sample List ID and Entrez Gene IDs","required":true,"schema":{"$ref":"#/definitions/MolecularDataFilter"}},{"name":"molecularProfileId","in":"path","description":"Molecular Profile ID e.g. acc_tcga_rna_seq_v2_mrna","required":true,"type":"string"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/NumericGeneMolecularData"}}}}}},"/molecular-profiles/{molecularProfileId}/mutations":{"get":{"tags":["Mutations"],"summary":"Get mutations in a molecular profile by Sample List ID","operationId":"getMutationsInMolecularProfileBySampleListIdUsingGET","produces":["application/json"],"parameters":[{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"entrezGeneId","in":"query","description":"Entrez Gene ID","required":false,"type":"integer","format":"int32"},{"name":"molecularProfileId","in":"path","description":"Molecular Profile ID e.g. acc_tcga_mutations","required":true,"type":"string"},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sampleListId","in":"query","description":"Sample List ID e.g. acc_tcga_all","required":true,"type":"string"},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["aminoAcidChange","center","endPosition","entrezGeneId","keyword","mutationStatus","mutationType","ncbiBuild","normalAltCount","normalRefCount","proteinChange","proteinPosEnd","proteinPosStart","referenceAllele","refseqMrnaId","startPosition","tumorAltCount","tumorRefCount","validationStatus","variantAllele","variantType"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/Mutation"}}}}}},"/molecular-profiles/{molecularProfileId}/mutations/fetch":{"post":{"tags":["Mutations"],"summary":"Fetch mutations in a molecular profile","operationId":"fetchMutationsInMolecularProfileUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"molecularProfileId","in":"path","description":"Molecular Profile ID e.g. acc_tcga_mutations","required":true,"type":"string"},{"in":"body","name":"mutationFilter","description":"List of Sample IDs/Sample List ID and Entrez Gene IDs","required":true,"schema":{"$ref":"#/definitions/MutationFilter"}},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["aminoAcidChange","center","endPosition","entrezGeneId","keyword","mutationStatus","mutationType","ncbiBuild","normalAltCount","normalRefCount","proteinChange","proteinPosEnd","proteinPosStart","referenceAllele","refseqMrnaId","startPosition","tumorAltCount","tumorRefCount","validationStatus","variantAllele","variantType"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/Mutation"}}}}}},"/mutations/fetch":{"post":{"tags":["Mutations"],"summary":"Fetch mutations in multiple molecular profiles by sample IDs","operationId":"fetchMutationsInMultipleMolecularProfilesUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"in":"body","name":"mutationMultipleStudyFilter","description":"List of Molecular Profile IDs or List of Molecular Profile ID / Sample ID pairs, and List of Entrez Gene IDs","required":true,"schema":{"$ref":"#/definitions/MutationMultipleStudyFilter"}},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["aminoAcidChange","center","endPosition","entrezGeneId","keyword","mutationStatus","mutationType","ncbiBuild","normalAltCount","normalRefCount","proteinChange","proteinPosEnd","proteinPosStart","referenceAllele","refseqMrnaId","startPosition","tumorAltCount","tumorRefCount","validationStatus","variantAllele","variantType"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/Mutation"}}}}}},"/patients":{"get":{"tags":["Patients"],"summary":"Get all patients","operationId":"getAllPatientsUsingGET","produces":["application/json"],"parameters":[{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"keyword","in":"query","description":"Search keyword that applies to ID of the patients","required":false,"type":"string"},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["patientId"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/Patient"}}}}}},"/patients/fetch":{"post":{"tags":["Patients"],"summary":"fetchPatients","operationId":"fetchPatientsUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"in":"body","name":"patientFilter","description":"List of patient identifiers","required":true,"schema":{"$ref":"#/definitions/PatientFilter"}},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/Patient"}}}}}},"/sample-lists":{"get":{"tags":["Sample Lists"],"summary":"Get all sample lists","operationId":"getAllSampleListsUsingGET","produces":["application/json"],"parameters":[{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["category","description","name","sampleListId","studyId"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/SampleList"}}}}}},"/sample-lists/fetch":{"post":{"tags":["Sample Lists"],"summary":"Fetch sample lists by ID","operationId":"fetchSampleListsUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"in":"body","name":"sampleListIds","description":"List of sample list IDs","required":true,"schema":{"type":"array","items":{"type":"string"}}}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/SampleList"}}}}}},"/sample-lists/{sampleListId}":{"get":{"tags":["Sample Lists"],"summary":"Get sample list","operationId":"getSampleListUsingGET","produces":["application/json"],"parameters":[{"name":"sampleListId","in":"path","description":"Sample List ID e.g. acc_tcga_all","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/SampleList"}}}}},"/sample-lists/{sampleListId}/sample-ids":{"get":{"tags":["Sample Lists"],"summary":"Get all sample IDs in a sample list","operationId":"getAllSampleIdsInSampleListUsingGET","produces":["application/json"],"parameters":[{"name":"sampleListId","in":"path","description":"Sample List ID e.g. acc_tcga_all","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"type":"string"}}}}}},"/samples":{"get":{"tags":["Samples"],"summary":"Get all samples matching keyword","operationId":"getSamplesByKeywordUsingGET","produces":["application/json"],"parameters":[{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"keyword","in":"query","description":"Search keyword that applies to the study ID","required":false,"type":"string"},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["sampleId","sampleType"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/Sample"}}}}}},"/samples/fetch":{"post":{"tags":["Samples"],"summary":"Fetch samples by ID","operationId":"fetchSamplesUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"in":"body","name":"sampleFilter","description":"List of sample identifiers","required":true,"schema":{"$ref":"#/definitions/SampleFilter"}}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/Sample"}}}}}},"/studies":{"get":{"tags":["Studies"],"summary":"Get all studies","operationId":"getAllStudiesUsingGET","produces":["application/json"],"parameters":[{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"keyword","in":"query","description":"Search keyword that applies to name and cancer type of the studies","required":false,"type":"string"},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["cancerTypeId","citation","description","groups","importDate","name","pmid","publicStudy","status","studyId"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/CancerStudy"}}}}}},"/studies/fetch":{"post":{"tags":["Studies"],"summary":"Fetch studies by IDs","operationId":"fetchStudiesUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"in":"body","name":"studyIds","description":"List of Study IDs","required":true,"schema":{"type":"array","items":{"type":"string"}}}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/CancerStudy"}}}}}},"/studies/tags/fetch":{"post":{"tags":["Studies"],"summary":"Get the study tags by IDs","operationId":"getTagsForMultipleStudiesUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"in":"body","name":"studyIds","description":"List of Study IDs","required":true,"schema":{"type":"array","items":{"type":"string"}}}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/CancerStudyTags"}}}}}},"/studies/{studyId}":{"get":{"tags":["Studies"],"summary":"Get a study","operationId":"getStudyUsingGET","produces":["application/json"],"parameters":[{"name":"studyId","in":"path","description":"Study ID e.g. acc_tcga","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/CancerStudy"}}}}},"/studies/{studyId}/clinical-attributes":{"get":{"tags":["Clinical Attributes"],"summary":"Get all clinical attributes in the specified study","operationId":"getAllClinicalAttributesInStudyUsingGET","produces":["application/json"],"parameters":[{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["clinicalAttributeId","datatype","description","displayName","patientAttribute","priority","studyId"]},{"name":"studyId","in":"path","description":"Study ID e.g. acc_tcga","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/ClinicalAttribute"}}}}}},"/studies/{studyId}/clinical-attributes/{clinicalAttributeId}":{"get":{"tags":["Clinical Attributes"],"summary":"Get specified clinical attribute","operationId":"getClinicalAttributeInStudyUsingGET","produces":["application/json"],"parameters":[{"name":"clinicalAttributeId","in":"path","description":"Clinical Attribute ID e.g. CANCER_TYPE","required":true,"type":"string"},{"name":"studyId","in":"path","description":"Study ID e.g. acc_tcga","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/ClinicalAttribute"}}}}},"/studies/{studyId}/clinical-data":{"get":{"tags":["Clinical Data"],"summary":"Get all clinical data in a study","operationId":"getAllClinicalDataInStudyUsingGET","produces":["application/json"],"parameters":[{"name":"attributeId","in":"query","description":"Attribute ID e.g. CANCER_TYPE","required":false,"type":"string"},{"name":"clinicalDataType","in":"query","description":"Type of the clinical data","required":false,"type":"string","default":"SAMPLE","enum":["PATIENT","SAMPLE"]},{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["clinicalAttributeId","value"]},{"name":"studyId","in":"path","description":"Study ID e.g. acc_tcga","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/ClinicalData"}}}}}},"/studies/{studyId}/clinical-data/fetch":{"post":{"tags":["Clinical Data"],"summary":"Fetch clinical data by patient IDs or sample IDs (specific study)","operationId":"fetchAllClinicalDataInStudyUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"in":"body","name":"clinicalDataSingleStudyFilter","description":"List of patient or sample IDs and attribute IDs","required":true,"schema":{"$ref":"#/definitions/ClinicalDataSingleStudyFilter"}},{"name":"clinicalDataType","in":"query","description":"Type of the clinical data","required":false,"type":"string","default":"SAMPLE","enum":["PATIENT","SAMPLE"]},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"studyId","in":"path","description":"Study ID e.g. acc_tcga","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/ClinicalData"}}}}}},"/studies/{studyId}/molecular-profiles":{"get":{"tags":["Molecular Profiles"],"summary":"Get all molecular profiles in a study","operationId":"getAllMolecularProfilesInStudyUsingGET","produces":["application/json"],"parameters":[{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["datatype","description","molecularAlterationType","molecularProfileId","name","showProfileInAnalysisTab"]},{"name":"studyId","in":"path","description":"Study ID e.g. acc_tcga","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/MolecularProfile"}}}}}},"/studies/{studyId}/patients":{"get":{"tags":["Patients"],"summary":"Get all patients in a study","operationId":"getAllPatientsInStudyUsingGET","produces":["application/json"],"parameters":[{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["patientId"]},{"name":"studyId","in":"path","description":"Study ID e.g. acc_tcga","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/Patient"}}}}}},"/studies/{studyId}/patients/{patientId}":{"get":{"tags":["Patients"],"summary":"Get a patient in a study","operationId":"getPatientInStudyUsingGET","produces":["application/json"],"parameters":[{"name":"patientId","in":"path","description":"Patient ID e.g. TCGA-OR-A5J2","required":true,"type":"string"},{"name":"studyId","in":"path","description":"Study ID e.g. acc_tcga","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/Patient"}}}}},"/studies/{studyId}/patients/{patientId}/clinical-data":{"get":{"tags":["Clinical Data"],"summary":"Get all clinical data of a patient in a study","operationId":"getAllClinicalDataOfPatientInStudyUsingGET","produces":["application/json"],"parameters":[{"name":"attributeId","in":"query","description":"Attribute ID e.g. AGE","required":false,"type":"string"},{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"patientId","in":"path","description":"Patient ID e.g. TCGA-OR-A5J2","required":true,"type":"string"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["clinicalAttributeId","value"]},{"name":"studyId","in":"path","description":"Study ID e.g. acc_tcga","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/ClinicalData"}}}}}},"/studies/{studyId}/patients/{patientId}/samples":{"get":{"tags":["Samples"],"summary":"Get all samples of a patient in a study","operationId":"getAllSamplesOfPatientInStudyUsingGET","produces":["application/json"],"parameters":[{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"patientId","in":"path","description":"Patient ID e.g. TCGA-OR-A5J2","required":true,"type":"string"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["sampleId","sampleType"]},{"name":"studyId","in":"path","description":"Study ID e.g. acc_tcga","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/Sample"}}}}}},"/studies/{studyId}/sample-lists":{"get":{"tags":["Sample Lists"],"summary":"Get all sample lists in a study","operationId":"getAllSampleListsInStudyUsingGET","produces":["application/json"],"parameters":[{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["category","description","name","sampleListId","studyId"]},{"name":"studyId","in":"path","description":"Study ID e.g. acc_tcga","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/SampleList"}}}}}},"/studies/{studyId}/samples":{"get":{"tags":["Samples"],"summary":"Get all samples in a study","operationId":"getAllSamplesInStudyUsingGET","produces":["application/json"],"parameters":[{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["sampleId","sampleType"]},{"name":"studyId","in":"path","description":"Study ID e.g. acc_tcga","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/Sample"}}}}}},"/studies/{studyId}/samples/{sampleId}":{"get":{"tags":["Samples"],"summary":"Get a sample in a study","operationId":"getSampleInStudyUsingGET","produces":["application/json"],"parameters":[{"name":"sampleId","in":"path","description":"Sample ID e.g. TCGA-OR-A5J2-01","required":true,"type":"string"},{"name":"studyId","in":"path","description":"Study ID e.g. acc_tcga","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/Sample"}}}}},"/studies/{studyId}/samples/{sampleId}/clinical-data":{"get":{"tags":["Clinical Data"],"summary":"Get all clinical data of a sample in a study","operationId":"getAllClinicalDataOfSampleInStudyUsingGET","produces":["application/json"],"parameters":[{"name":"attributeId","in":"query","description":"Attribute ID e.g. CANCER_TYPE","required":false,"type":"string"},{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":10000000,"maximum":10000000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sampleId","in":"path","description":"Sample ID e.g. TCGA-OR-A5J2-01","required":true,"type":"string"},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["clinicalAttributeId","value"]},{"name":"studyId","in":"path","description":"Study ID e.g. acc_tcga","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/ClinicalData"}}}}}},"/studies/{studyId}/samples/{sampleId}/copy-number-segments":{"get":{"tags":["Copy Number Segments"],"summary":"Get copy number segments in a sample in a study","operationId":"getCopyNumberSegmentsInSampleInStudyUsingGET","produces":["application/json"],"parameters":[{"name":"chromosome","in":"query","description":"Chromosome","required":false,"type":"string"},{"name":"direction","in":"query","description":"Direction of the sort","required":false,"type":"string","default":"ASC","enum":["ASC","DESC"]},{"name":"pageNumber","in":"query","description":"Page number of the result list","required":false,"type":"integer","default":0,"minimum":0,"exclusiveMinimum":false,"format":"int32"},{"name":"pageSize","in":"query","description":"Page size of the result list","required":false,"type":"integer","default":20000,"maximum":20000,"exclusiveMaximum":false,"minimum":1,"exclusiveMinimum":false,"format":"int32"},{"name":"projection","in":"query","description":"Level of detail of the response","required":false,"type":"string","default":"SUMMARY","enum":["DETAILED","ID","META","SUMMARY"]},{"name":"sampleId","in":"path","description":"Sample ID e.g. TCGA-OR-A5J2-01","required":true,"type":"string"},{"name":"sortBy","in":"query","description":"Name of the property that the result list is sorted by","required":false,"type":"string","enum":["chromosome","end","numberOfProbes","segmentMean","start"]},{"name":"studyId","in":"path","description":"Study ID e.g. acc_tcga","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/CopyNumberSeg"}}}}}},"/studies/{studyId}/tags":{"get":{"tags":["Studies"],"summary":"Get the tags of a study","operationId":"getTagsUsingGET","produces":["application/json"],"parameters":[{"name":"studyId","in":"path","description":"Study ID e.g. acc_tcga","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"type":"object"}}}}},"/treatments/display-patient":{"post":{"tags":["Treatments"],"summary":"Should patient level treatments be displayed","operationId":"getContainsTreatmentDataUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"in":"body","name":"studyIds","description":"List of Study IDs","required":true,"schema":{"type":"array","items":{"type":"string"}}},{"name":"tier","in":"query","description":"tier","required":false,"type":"string","default":"Agent","enum":["Agent","AgentClass","AgentTarget"]}],"responses":{"200":{"description":"OK","schema":{"type":"boolean"}}}}},"/treatments/display-sample":{"post":{"tags":["Treatments"],"summary":"Should sample level treatments be displayed","operationId":"getContainsSampleTreatmentDataUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"in":"body","name":"studyIds","description":"List of Study IDs","required":true,"schema":{"type":"array","items":{"type":"string"}}},{"name":"tier","in":"query","description":"tier","required":false,"type":"string","default":"Agent","enum":["Agent","AgentClass","AgentTarget"]}],"responses":{"200":{"description":"OK","schema":{"type":"boolean"}}}}},"/treatments/patient":{"post":{"tags":["Treatments"],"summary":"Get all patient level treatments","operationId":"getAllPatientTreatmentsUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"in":"body","name":"studyViewFilter","description":"Study view filter","required":true,"schema":{"$ref":"#/definitions/StudyViewFilter"}},{"name":"tier","in":"query","description":"tier","required":false,"type":"string","default":"Agent","enum":["Agent","AgentClass","AgentTarget"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/PatientTreatmentRow"}}}}}},"/treatments/sample":{"post":{"tags":["Treatments"],"summary":"Get all sample level treatments","operationId":"getAllSampleTreatmentsUsingPOST","consumes":["application/json"],"produces":["application/json"],"parameters":[{"in":"body","name":"studyViewFilter","description":"Study view filter","required":true,"schema":{"$ref":"#/definitions/StudyViewFilter"}},{"name":"tier","in":"query","description":"tier","required":false,"type":"string","default":"Agent","enum":["Agent","AgentClass","AgentTarget"]}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/SampleTreatmentRow"}}}}}}},"definitions":{"AlleleSpecificCopyNumber":{"type":"object","properties":{"ascnIntegerCopyNumber":{"type":"integer","format":"int32"},"ascnMethod":{"type":"string"},"ccfExpectedCopies":{"type":"number","format":"float"},"ccfExpectedCopiesUpper":{"type":"number","format":"float"},"clonal":{"type":"string"},"expectedAltCopies":{"type":"integer","format":"int32"},"minorCopyNumber":{"type":"integer","format":"int32"},"totalCopyNumber":{"type":"integer","format":"int32"}},"title":"AlleleSpecificCopyNumber"},"AlterationFilter":{"type":"object","properties":{"copyNumberAlterationEventTypes":{"type":"object","additionalProperties":{"type":"boolean"}},"includeDriver":{"type":"boolean"},"includeGermline":{"type":"boolean"},"includeSomatic":{"type":"boolean"},"includeUnknownOncogenicity":{"type":"boolean"},"includeUnknownStatus":{"type":"boolean"},"includeUnknownTier":{"type":"boolean"},"includeVUS":{"type":"boolean"},"mutationEventTypes":{"type":"object","additionalProperties":{"type":"boolean"}},"structuralVariants":{"type":"boolean"},"tiersBooleanMap":{"type":"object","additionalProperties":{"type":"boolean"}}},"title":"AlterationFilter"},"AndedPatientTreatmentFilters":{"type":"object","properties":{"filters":{"type":"array","items":{"$ref":"#/definitions/OredPatientTreatmentFilters"}}},"title":"AndedPatientTreatmentFilters"},"AndedSampleTreatmentFilters":{"type":"object","properties":{"filters":{"type":"array","items":{"$ref":"#/definitions/OredSampleTreatmentFilters"}}},"title":"AndedSampleTreatmentFilters"},"CancerStudy":{"type":"object","required":["studyId"],"properties":{"allSampleCount":{"type":"integer","format":"int32"},"cancerType":{"$ref":"#/definitions/TypeOfCancer"},"cancerTypeId":{"type":"string"},"citation":{"type":"string"},"cnaSampleCount":{"type":"integer","format":"int32"},"completeSampleCount":{"type":"integer","format":"int32"},"description":{"type":"string"},"groups":{"type":"string"},"importDate":{"type":"string","example":"yyyy-MM-dd HH:mm:ss"},"massSpectrometrySampleCount":{"type":"integer","format":"int32"},"methylationHm27SampleCount":{"type":"integer","format":"int32"},"miRnaSampleCount":{"type":"integer","format":"int32"},"mrnaMicroarraySampleCount":{"type":"integer","format":"int32"},"mrnaRnaSeqSampleCount":{"type":"integer","format":"int32"},"mrnaRnaSeqV2SampleCount":{"type":"integer","format":"int32"},"name":{"type":"string"},"pmid":{"type":"string"},"publicStudy":{"type":"boolean"},"readPermission":{"type":"boolean"},"referenceGenome":{"type":"string"},"rppaSampleCount":{"type":"integer","format":"int32"},"sequencedSampleCount":{"type":"integer","format":"int32"},"status":{"type":"integer","format":"int32"},"studyId":{"type":"string"},"treatmentCount":{"type":"integer","format":"int32"}},"title":"CancerStudy"},"CancerStudyTags":{"type":"object","properties":{"cancerStudyId":{"type":"integer","format":"int32"},"studyId":{"type":"string"},"tags":{"type":"string"}},"title":"CancerStudyTags"},"ClinicalAttribute":{"type":"object","required":["clinicalAttributeId","displayName","patientAttribute","studyId"],"properties":{"clinicalAttributeId":{"type":"string"},"datatype":{"type":"string"},"description":{"type":"string"},"displayName":{"type":"string"},"patientAttribute":{"type":"boolean"},"priority":{"type":"string"},"studyId":{"type":"string"}},"title":"ClinicalAttribute"},"ClinicalData":{"type":"object","required":["clinicalAttributeId","patientId","studyId"],"properties":{"clinicalAttribute":{"$ref":"#/definitions/ClinicalAttribute"},"clinicalAttributeId":{"type":"string"},"patientAttribute":{"type":"boolean"},"patientId":{"type":"string"},"sampleId":{"type":"string"},"studyId":{"type":"string"},"uniquePatientKey":{"type":"string"},"uniqueSampleKey":{"type":"string"},"value":{"type":"string"}},"title":"ClinicalData"},"ClinicalDataFilter":{"type":"object","properties":{"attributeId":{"type":"string"},"values":{"type":"array","items":{"$ref":"#/definitions/DataFilterValue"}}},"title":"ClinicalDataFilter"},"ClinicalDataIdentifier":{"type":"object","properties":{"entityId":{"type":"string"},"studyId":{"type":"string"}},"title":"ClinicalDataIdentifier"},"ClinicalDataMultiStudyFilter":{"type":"object","properties":{"attributeIds":{"type":"array","items":{"type":"string"}},"identifiers":{"type":"array","items":{"$ref":"#/definitions/ClinicalDataIdentifier"}}},"title":"ClinicalDataMultiStudyFilter"},"ClinicalDataSingleStudyFilter":{"type":"object","properties":{"attributeIds":{"type":"array","items":{"type":"string"}},"ids":{"type":"array","items":{"type":"string"}}},"title":"ClinicalDataSingleStudyFilter"},"ClinicalEventSample":{"type":"object","properties":{"patientId":{"type":"string"},"sampleId":{"type":"string"},"studyId":{"type":"string"},"timeTaken":{"type":"integer","format":"int32"}},"title":"ClinicalEventSample"},"CopyNumberSeg":{"type":"object","required":["chromosome","end","numberOfProbes","patientId","sampleId","segmentMean","start","studyId"],"properties":{"chromosome":{"type":"string"},"end":{"type":"integer","format":"int32"},"numberOfProbes":{"type":"integer","format":"int32"},"patientId":{"type":"string"},"sampleId":{"type":"string"},"segmentMean":{"type":"number"},"start":{"type":"integer","format":"int32"},"studyId":{"type":"string"},"uniquePatientKey":{"type":"string"},"uniqueSampleKey":{"type":"string"}},"title":"CopyNumberSeg"},"DataFilter":{"type":"object","properties":{"values":{"type":"array","items":{"$ref":"#/definitions/DataFilterValue"}}},"title":"DataFilter"},"DataFilterValue":{"type":"object","properties":{"end":{"type":"number"},"start":{"type":"number"},"value":{"type":"string"}},"title":"DataFilterValue"},"DiscreteCopyNumberData":{"type":"object","required":["alteration","entrezGeneId","molecularProfileId","patientId","sampleId","studyId"],"properties":{"alteration":{"type":"integer","format":"int32"},"driverFilter":{"type":"string"},"driverFilterAnnotation":{"type":"string"},"driverTiersFilter":{"type":"string"},"driverTiersFilterAnnotation":{"type":"string"},"entrezGeneId":{"type":"integer","format":"int32"},"gene":{"$ref":"#/definitions/Gene"},"molecularProfileId":{"type":"string"},"namespaceColumns":{"type":"object","additionalProperties":{"type":"object"}},"patientId":{"type":"string"},"sampleId":{"type":"string"},"studyId":{"type":"string"},"uniquePatientKey":{"type":"string"},"uniqueSampleKey":{"type":"string"}},"title":"DiscreteCopyNumberData"},"DiscreteCopyNumberFilter":{"type":"object","properties":{"entrezGeneIds":{"type":"array","items":{"type":"integer","format":"int32"}},"sampleIds":{"type":"array","items":{"type":"string"}},"sampleListId":{"type":"string"}},"title":"DiscreteCopyNumberFilter"},"Gene":{"type":"object","required":["entrezGeneId","geneticEntityId","hugoGeneSymbol"],"properties":{"entrezGeneId":{"type":"integer","format":"int32"},"geneticEntityId":{"type":"integer","format":"int32"},"hugoGeneSymbol":{"type":"string"},"type":{"type":"string"}},"title":"Gene"},"GeneFilter":{"type":"object","properties":{"geneQueries":{"type":"array","items":{"type":"array","items":{"$ref":"#/definitions/GeneFilterQuery"}}},"molecularProfileIds":{"type":"array","uniqueItems":true,"items":{"type":"string"}}},"title":"GeneFilter"},"GeneFilterQuery":{"type":"object","properties":{"alterations":{"type":"array","items":{"type":"string","enum":["AMP","DIPLOID","GAIN","HETLOSS","HOMDEL"]}},"entrezGeneId":{"type":"integer","format":"int32"},"hugoGeneSymbol":{"type":"string"},"includeDriver":{"type":"boolean"},"includeGermline":{"type":"boolean"},"includeSomatic":{"type":"boolean"},"includeUnknownOncogenicity":{"type":"boolean"},"includeUnknownStatus":{"type":"boolean"},"includeUnknownTier":{"type":"boolean"},"includeVUS":{"type":"boolean"},"tiersBooleanMap":{"type":"object","additionalProperties":{"type":"boolean"}}},"title":"GeneFilterQuery"},"GenePanel":{"type":"object","required":["genePanelId"],"properties":{"description":{"type":"string"},"genePanelId":{"type":"string"},"genes":{"type":"array","items":{"$ref":"#/definitions/GenePanelToGene"}}},"title":"GenePanel"},"GenePanelData":{"type":"object","required":["molecularProfileId","patientId","profiled","sampleId","studyId"],"properties":{"genePanelId":{"type":"string"},"molecularProfileId":{"type":"string"},"patientId":{"type":"string"},"profiled":{"type":"boolean"},"sampleId":{"type":"string"},"studyId":{"type":"string"},"uniquePatientKey":{"type":"string"},"uniqueSampleKey":{"type":"string"}},"title":"GenePanelData"},"GenePanelDataFilter":{"type":"object","properties":{"sampleIds":{"type":"array","items":{"type":"string"}},"sampleListId":{"type":"string"}},"title":"GenePanelDataFilter"},"GenePanelDataMultipleStudyFilter":{"type":"object","properties":{"molecularProfileIds":{"type":"array","items":{"type":"string"}},"sampleMolecularIdentifiers":{"type":"array","items":{"$ref":"#/definitions/SampleMolecularIdentifier"}}},"title":"GenePanelDataMultipleStudyFilter"},"GenePanelToGene":{"type":"object","required":["entrezGeneId","hugoGeneSymbol"],"properties":{"entrezGeneId":{"type":"integer","format":"int32"},"hugoGeneSymbol":{"type":"string"}},"title":"GenePanelToGene"},"GenericAssayData":{"type":"object","required":["genericAssayStableId","molecularProfileId","patientId","sampleId","studyId","value"],"properties":{"genericAssayStableId":{"type":"string"},"molecularProfileId":{"type":"string"},"patientId":{"type":"string"},"sampleId":{"type":"string"},"stableId":{"type":"string"},"studyId":{"type":"string"},"uniquePatientKey":{"type":"string"},"uniqueSampleKey":{"type":"string"},"value":{"type":"string"}},"title":"GenericAssayData"},"GenericAssayDataFilter":{"type":"object","properties":{"profileType":{"type":"string"},"stableId":{"type":"string"},"values":{"type":"array","items":{"$ref":"#/definitions/DataFilterValue"}}},"title":"GenericAssayDataFilter"},"GenericAssayDataMultipleStudyFilter":{"type":"object","properties":{"genericAssayStableIds":{"type":"array","items":{"type":"string"}},"molecularProfileIds":{"type":"array","items":{"type":"string"}},"sampleMolecularIdentifiers":{"type":"array","items":{"$ref":"#/definitions/SampleMolecularIdentifier"}}},"title":"GenericAssayDataMultipleStudyFilter"},"GenericAssayFilter":{"type":"object","properties":{"genericAssayStableIds":{"type":"array","items":{"type":"string"}},"sampleIds":{"type":"array","items":{"type":"string"}},"sampleListId":{"type":"string"}},"title":"GenericAssayFilter"},"GenericAssayMeta":{"type":"object","properties":{"entityType":{"type":"string"},"genericEntityMetaProperties":{"type":"object","additionalProperties":{"type":"string"}},"stableId":{"type":"string"}},"title":"GenericAssayMeta"},"GenericAssayMetaFilter":{"type":"object","properties":{"genericAssayStableIds":{"type":"array","items":{"type":"string"}},"molecularProfileIds":{"type":"array","items":{"type":"string"}}},"title":"GenericAssayMetaFilter"},"GenomicDataFilter":{"type":"object","properties":{"hugoGeneSymbol":{"type":"string"},"profileType":{"type":"string"},"values":{"type":"array","items":{"$ref":"#/definitions/DataFilterValue"}}},"title":"GenomicDataFilter"},"Info":{"type":"object","required":["dbVersion","gitBranch","gitCommitId","gitCommitIdAbbrev","gitCommitIdDescribe","gitCommitIdDescribeShort","gitCommitMessageFull","gitCommitMessageShort","gitCommitMessageUserEmail","gitCommitMessageUserName","gitDirty","portalVersion"],"properties":{"dbVersion":{"type":"string"},"gitBranch":{"type":"string"},"gitCommitId":{"type":"string"},"gitCommitIdAbbrev":{"type":"string"},"gitCommitIdDescribe":{"type":"string"},"gitCommitIdDescribeShort":{"type":"string"},"gitCommitMessageFull":{"type":"string"},"gitCommitMessageShort":{"type":"string"},"gitCommitMessageUserEmail":{"type":"string"},"gitCommitMessageUserName":{"type":"string"},"gitDirty":{"type":"boolean"},"portalVersion":{"type":"string"}},"title":"Info"},"MolecularDataFilter":{"type":"object","properties":{"entrezGeneIds":{"type":"array","items":{"type":"integer","format":"int32"}},"sampleIds":{"type":"array","items":{"type":"string"}},"sampleListId":{"type":"string"}},"title":"MolecularDataFilter"},"MolecularDataMultipleStudyFilter":{"type":"object","properties":{"entrezGeneIds":{"type":"array","items":{"type":"integer","format":"int32"}},"molecularProfileIds":{"type":"array","items":{"type":"string"}},"sampleMolecularIdentifiers":{"type":"array","items":{"$ref":"#/definitions/SampleMolecularIdentifier"}}},"title":"MolecularDataMultipleStudyFilter"},"MolecularProfile":{"type":"object","required":["molecularProfileId","patientLevel","studyId"],"properties":{"datatype":{"type":"string"},"description":{"type":"string"},"genericAssayType":{"type":"string"},"molecularAlterationType":{"type":"string","enum":["COPY_NUMBER_ALTERATION","GENERIC_ASSAY","GENESET_SCORE","METHYLATION","METHYLATION_BINARY","MICRO_RNA_EXPRESSION","MRNA_EXPRESSION","MRNA_EXPRESSION_NORMALS","MUTATION_EXTENDED","MUTATION_UNCALLED","PHOSPHORYLATION","PROTEIN_ARRAY_PHOSPHORYLATION","PROTEIN_ARRAY_PROTEIN_LEVEL","PROTEIN_LEVEL","RNA_EXPRESSION","STRUCTURAL_VARIANT"]},"molecularProfileId":{"type":"string"},"name":{"type":"string"},"patientLevel":{"type":"boolean"},"pivotThreshold":{"type":"number","format":"float"},"showProfileInAnalysisTab":{"type":"boolean"},"sortOrder":{"type":"string"},"study":{"$ref":"#/definitions/CancerStudy"},"studyId":{"type":"string"}},"title":"MolecularProfile"},"MolecularProfileFilter":{"type":"object","properties":{"molecularProfileIds":{"type":"array","uniqueItems":true,"items":{"type":"string"}},"studyIds":{"type":"array","items":{"type":"string"}}},"title":"MolecularProfileFilter"},"Mutation":{"type":"object","required":["entrezGeneId","molecularProfileId","patientId","sampleId","studyId"],"properties":{"alleleSpecificCopyNumber":{"$ref":"#/definitions/AlleleSpecificCopyNumber"},"aminoAcidChange":{"type":"string"},"center":{"type":"string"},"chr":{"type":"string"},"driverFilter":{"type":"string"},"driverFilterAnnotation":{"type":"string"},"driverTiersFilter":{"type":"string"},"driverTiersFilterAnnotation":{"type":"string"},"endPosition":{"type":"integer","format":"int64"},"entrezGeneId":{"type":"integer","format":"int32"},"gene":{"$ref":"#/definitions/Gene"},"keyword":{"type":"string"},"molecularProfileId":{"type":"string"},"mutationStatus":{"type":"string"},"mutationType":{"type":"string"},"namespaceColumns":{"type":"object","additionalProperties":{"type":"object"}},"ncbiBuild":{"type":"string"},"normalAltCount":{"type":"integer","format":"int32"},"normalRefCount":{"type":"integer","format":"int32"},"patientId":{"type":"string"},"proteinChange":{"type":"string"},"proteinPosEnd":{"type":"integer","format":"int32"},"proteinPosStart":{"type":"integer","format":"int32"},"referenceAllele":{"type":"string"},"refseqMrnaId":{"type":"string"},"sampleId":{"type":"string"},"startPosition":{"type":"integer","format":"int64"},"studyId":{"type":"string"},"tumorAltCount":{"type":"integer","format":"int32"},"tumorRefCount":{"type":"integer","format":"int32"},"uniquePatientKey":{"type":"string"},"uniqueSampleKey":{"type":"string"},"validationStatus":{"type":"string"},"variantAllele":{"type":"string"},"variantType":{"type":"string"}},"title":"Mutation"},"MutationFilter":{"type":"object","properties":{"entrezGeneIds":{"type":"array","items":{"type":"integer","format":"int32"}},"sampleIds":{"type":"array","items":{"type":"string"}},"sampleListId":{"type":"string"}},"title":"MutationFilter"},"MutationMultipleStudyFilter":{"type":"object","properties":{"entrezGeneIds":{"type":"array","items":{"type":"integer","format":"int32"}},"molecularProfileIds":{"type":"array","items":{"type":"string"}},"sampleMolecularIdentifiers":{"type":"array","items":{"$ref":"#/definitions/SampleMolecularIdentifier"}}},"title":"MutationMultipleStudyFilter"},"NumericGeneMolecularData":{"type":"object","required":["entrezGeneId","molecularProfileId","patientId","sampleId","studyId","value"],"properties":{"entrezGeneId":{"type":"integer","format":"int32"},"gene":{"$ref":"#/definitions/Gene"},"molecularProfileId":{"type":"string"},"patientId":{"type":"string"},"sampleId":{"type":"string"},"studyId":{"type":"string"},"uniquePatientKey":{"type":"string"},"uniqueSampleKey":{"type":"string"},"value":{"type":"number"}},"title":"NumericGeneMolecularData"},"OredPatientTreatmentFilters":{"type":"object","properties":{"filters":{"type":"array","items":{"$ref":"#/definitions/PatientTreatmentFilter"}}},"title":"OredPatientTreatmentFilters"},"OredSampleTreatmentFilters":{"type":"object","properties":{"filters":{"type":"array","items":{"$ref":"#/definitions/SampleTreatmentFilter"}}},"title":"OredSampleTreatmentFilters"},"Patient":{"type":"object","required":["patientId","studyId"],"properties":{"cancerStudy":{"$ref":"#/definitions/CancerStudy"},"patientId":{"type":"string"},"studyId":{"type":"string"},"uniquePatientKey":{"type":"string"},"uniqueSampleKey":{"type":"string"}},"title":"Patient"},"PatientFilter":{"type":"object","properties":{"patientIdentifiers":{"type":"array","items":{"$ref":"#/definitions/PatientIdentifier"}},"uniquePatientKeys":{"type":"array","items":{"type":"string"}}},"title":"PatientFilter"},"PatientIdentifier":{"type":"object","properties":{"patientId":{"type":"string"},"studyId":{"type":"string"}},"title":"PatientIdentifier"},"PatientTreatmentFilter":{"type":"object","properties":{"treatment":{"type":"string"}},"title":"PatientTreatmentFilter"},"PatientTreatmentRow":{"type":"object","properties":{"count":{"type":"integer","format":"int32"},"samples":{"type":"array","uniqueItems":true,"items":{"$ref":"#/definitions/ClinicalEventSample"}},"treatment":{"type":"string"}},"title":"PatientTreatmentRow"},"Sample":{"type":"object","required":["patientId","sampleId","studyId"],"properties":{"copyNumberSegmentPresent":{"type":"boolean"},"patientId":{"type":"string"},"sampleId":{"type":"string"},"sampleType":{"type":"string","enum":["BLOOD_NORMAL","METASTATIC","PRIMARY_BLOOD_TUMOR","PRIMARY_SOLID_TUMOR","RECURRENT_BLOOD_TUMOR","RECURRENT_SOLID_TUMOR","SOLID_NORMAL"]},"sequenced":{"type":"boolean"},"studyId":{"type":"string"},"uniquePatientKey":{"type":"string"},"uniqueSampleKey":{"type":"string"}},"title":"Sample"},"SampleFilter":{"type":"object","properties":{"sampleIdentifiers":{"type":"array","items":{"$ref":"#/definitions/SampleIdentifier"}},"sampleListIds":{"type":"array","items":{"type":"string"}},"uniqueSampleKeys":{"type":"array","items":{"type":"string"}}},"title":"SampleFilter"},"SampleIdentifier":{"type":"object","properties":{"sampleId":{"type":"string"},"studyId":{"type":"string"}},"title":"SampleIdentifier"},"SampleList":{"type":"object","required":["sampleListId"],"properties":{"category":{"type":"string"},"description":{"type":"string"},"name":{"type":"string"},"sampleCount":{"type":"integer","format":"int32"},"sampleIds":{"type":"array","items":{"type":"string"}},"sampleListId":{"type":"string"},"studyId":{"type":"string"}},"title":"SampleList"},"SampleMolecularIdentifier":{"type":"object","properties":{"molecularProfileId":{"type":"string"},"sampleId":{"type":"string"}},"title":"SampleMolecularIdentifier"},"SampleTreatmentFilter":{"type":"object","properties":{"time":{"type":"string","enum":["Post","Pre"]},"treatment":{"type":"string"}},"title":"SampleTreatmentFilter"},"SampleTreatmentRow":{"type":"object","properties":{"count":{"type":"integer","format":"int32"},"samples":{"type":"array","uniqueItems":true,"items":{"$ref":"#/definitions/ClinicalEventSample"}},"time":{"type":"string","enum":["Post","Pre"]},"treatment":{"type":"string"}},"title":"SampleTreatmentRow"},"ServerStatusMessage":{"type":"object","properties":{"status":{"type":"string"}},"title":"ServerStatusMessage"},"StructuralVariantFilterQuery":{"type":"object","properties":{"gene1Query":{"$ref":"#/definitions/StructuralVariantGeneSubQuery"},"gene2Query":{"$ref":"#/definitions/StructuralVariantGeneSubQuery"},"includeDriver":{"type":"boolean"},"includeGermline":{"type":"boolean"},"includeSomatic":{"type":"boolean"},"includeUnknownOncogenicity":{"type":"boolean"},"includeUnknownStatus":{"type":"boolean"},"includeUnknownTier":{"type":"boolean"},"includeVUS":{"type":"boolean"},"tiersBooleanMap":{"type":"object","additionalProperties":{"type":"boolean"}}},"title":"StructuralVariantFilterQuery"},"StructuralVariantGeneSubQuery":{"type":"object","properties":{"entrezId":{"type":"integer","format":"int32"},"hugoSymbol":{"type":"string"},"specialValue":{"type":"string","enum":["ANY_GENE","NO_GENE"]}},"title":"StructuralVariantGeneSubQuery"},"StudyViewFilter":{"type":"object","properties":{"alterationFilter":{"$ref":"#/definitions/AlterationFilter"},"caseLists":{"type":"array","items":{"type":"array","items":{"type":"string"}}},"clinicalDataFilters":{"type":"array","items":{"$ref":"#/definitions/ClinicalDataFilter"}},"clinicalEventFilters":{"type":"array","items":{"$ref":"#/definitions/DataFilter"}},"customDataFilters":{"type":"array","items":{"$ref":"#/definitions/ClinicalDataFilter"}},"geneFilters":{"type":"array","items":{"$ref":"#/definitions/GeneFilter"}},"genericAssayDataFilters":{"type":"array","items":{"$ref":"#/definitions/GenericAssayDataFilter"}},"genomicDataFilters":{"type":"array","items":{"$ref":"#/definitions/GenomicDataFilter"}},"genomicProfiles":{"type":"array","items":{"type":"array","items":{"type":"string"}}},"patientTreatmentFilters":{"$ref":"#/definitions/AndedPatientTreatmentFilters"},"patientTreatmentGroupFilters":{"$ref":"#/definitions/AndedPatientTreatmentFilters"},"patientTreatmentTargetFilters":{"$ref":"#/definitions/AndedPatientTreatmentFilters"},"sampleIdentifiers":{"type":"array","items":{"$ref":"#/definitions/SampleIdentifier"}},"sampleTreatmentFilters":{"$ref":"#/definitions/AndedSampleTreatmentFilters"},"sampleTreatmentGroupFilters":{"$ref":"#/definitions/AndedSampleTreatmentFilters"},"sampleTreatmentTargetFilters":{"$ref":"#/definitions/AndedSampleTreatmentFilters"},"structuralVariantFilters":{"type":"array","items":{"$ref":"#/definitions/StudyViewStructuralVariantFilter"}},"studyIds":{"type":"array","items":{"type":"string"}}},"title":"StudyViewFilter"},"StudyViewStructuralVariantFilter":{"type":"object","properties":{"molecularProfileIds":{"type":"array","uniqueItems":true,"items":{"type":"string"}},"structVarQueries":{"type":"array","items":{"type":"array","items":{"$ref":"#/definitions/StructuralVariantFilterQuery"}}}},"title":"StudyViewStructuralVariantFilter"},"TypeOfCancer":{"type":"object","required":["cancerTypeId"],"properties":{"cancerTypeId":{"type":"string"},"dedicatedColor":{"type":"string"},"name":{"type":"string"},"parent":{"type":"string"},"shortName":{"type":"string"}},"title":"TypeOfCancer"}}} diff --git a/src/main/resources/org/cbioportal/persistence/mybatis/MutationMapper.xml b/src/main/resources/org/cbioportal/persistence/mybatis/MutationMapper.xml index bc74b1c98dc..de6a18dc104 100644 --- a/src/main/resources/org/cbioportal/persistence/mybatis/MutationMapper.xml +++ b/src/main/resources/org/cbioportal/persistence/mybatis/MutationMapper.xml @@ -92,7 +92,7 @@ - + AND mutation_event.REFERENCE_ALLELE IN ('A','T','C','G') AND mutation_event.TUMOR_SEQ_ALLELE IN ('A','T','C','G') @@ -115,7 +115,7 @@ #{item} - + AND mutation_event.REFERENCE_ALLELE IN ('A','T','C','G') AND mutation_event.TUMOR_SEQ_ALLELE IN ('A','T','C','G') @@ -165,7 +165,7 @@ - + AND mutation_event.REFERENCE_ALLELE IN ('A','T','C','G') AND mutation_event.TUMOR_SEQ_ALLELE IN ('A','T','C','G') @@ -275,6 +275,20 @@ AND mutation.SAMPLE_ID = allele_specific_copy_number.SAMPLE_ID + + + + + + + + + + + + + + + + diff --git a/src/main/resources/org/cbioportal/persistence/mybatis/StudyMapper.xml b/src/main/resources/org/cbioportal/persistence/mybatis/StudyMapper.xml index 76f7dfed0dd..9b580a23507 100644 --- a/src/main/resources/org/cbioportal/persistence/mybatis/StudyMapper.xml +++ b/src/main/resources/org/cbioportal/persistence/mybatis/StudyMapper.xml @@ -35,9 +35,15 @@ COUNT(CASE WHEN sample_list.STABLE_ID = CONCAT(cancer_study.CANCER_STUDY_IDENTIFIER,'_protein_quantification') THEN 1 ELSE NULL END) AS massSpectrometrySampleCount, COUNT(CASE WHEN sample_list.STABLE_ID = CONCAT(cancer_study.CANCER_STUDY_IDENTIFIER,'_3way_complete') THEN 1 ELSE NULL END) AS completeSampleCount, IFNULL(treatment.count, 0 ) as treatmentCount, - - - + COALESCE(structural_variant.count, 0) as structuralVariantCount, + type_of_cancer.TYPE_OF_CANCER_ID AS "typeOfCancer.typeOfCancerId" + + , + type_of_cancer.NAME AS "typeOfCancer.name", + type_of_cancer.DEDICATED_COLOR AS "typeOfCancer.dedicatedColor", + type_of_cancer.SHORT_NAME AS "typeOfCancer.shortName", + type_of_cancer.PARENT AS "typeOfCancer.parent" + @@ -57,6 +63,16 @@ WHERE clinical_event.EVENT_TYPE = 'Treatment' GROUP BY patient.CANCER_STUDY_ID ) as treatment on cancer_study.CANCER_STUDY_ID = treatment.CANCER_STUDY_ID + LEFT JOIN + ( + SELECT COUNT(DISTINCT(structural_variant.SAMPLE_ID)) as count, + patient.CANCER_STUDY_ID as CANCER_STUDY_ID + FROM cancer_study + INNER JOIN patient on cancer_study.CANCER_STUDY_ID = patient.CANCER_STUDY_ID + LEFT JOIN sample on patient.INTERNAL_ID = sample.PATIENT_ID + INNER JOIN structural_variant on structural_variant.SAMPLE_ID = sample.INTERNAL_ID + GROUP BY patient.CANCER_STUDY_ID + ) as structural_variant on structural_variant.CANCER_STUDY_ID = cancer_study.CANCER_STUDY_ID diff --git a/src/main/resources/portal.properties.EXAMPLE b/src/main/resources/portal.properties.EXAMPLE deleted file mode 100644 index dcb354c620a..00000000000 --- a/src/main/resources/portal.properties.EXAMPLE +++ /dev/null @@ -1,502 +0,0 @@ -# app name -app.name=cbioportal - -# Spring Properties - -spring.mvc.pathmatch.matching-strategy = ANT_PATH_MATCHER - -# database -spring.datasource.url=jdbc:mysql://localhost:3306/cbioportal?useSSL=false -spring.datasource.username=cbio -spring.datasource.password=P@ssword1 -spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect -#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver -spring.datasource.driver-class-name=com.mysql.jdbc.Driver - -# this should normally be set to false. In some cases you could set this to true (e.g. for testing a feature of a newer release that is not related to the schema change in expected db version above): -db.suppress_schema_version_mismatch_errors=false - -# authentication -authenticate=saml - -# set tomcat_resource_name when using dbconnector=jndi instead of the default -# dbconnector=dbcp. Note that dbconnector needs to be set in CATLINA_OPTS when -# using Tomcat (CATALINA_OPTS="-Ddbconnector=jndi"). It does not get picked up -# from the properties file -# (https://github.com/cBioPortal/cbioportal/issues/6148). -# -# db.tomcat_resource_name=jdbc/cbioportal - -# web page cosmetics -skin.title=cBioPortal for Cancer Genomics -skin.email_contact=cbioportal at googlegroups dot com -skin.authorization_message=Access to this portal is only available to authorized users at Memorial Sloan Kettering Cancer Center. [Request Access]. -skin.example_study_queries=tcga\ntcga -provisional\ntcga -moratorium\ntcga OR icgc\n-"cell line"\nprostate mskcc\nesophageal OR stomach\nserous\nbreast -skin.data_sets_header=The portal currently contains data from the following cancer genomics studies. The table below lists the number of available samples per data type and tumor. -skin.data_sets_footer=Data sets of TCGA studies were downloaded from Broad Firehose (http://gdac.broadinstitute.org) and updated monthly. In some studies, data sets were from the TCGA working groups directly. -#skin.examples_right_column_html= - -# documentation pages -skin.documentation.baseurl=https://raw.githubusercontent.com/cBioPortal/cbioportal/master/docs/ -skin.documentation.markdown=true -skin.documentation.faq=user-guide/faq.md -skin.documentation.about=About-Us.md -skin.documentation.news=News.md -skin.documentation.oql=Onco-Query-Language.md -skin.documentation.dat=Authenticating-Users-via-Tokens.md - -# setting controlling the logos -skin.right_logo= -skin.left_logo= -skin.tag_line_image=tag_line.png - -# setting controlling which tabs to hide. -skin.show_news_tab=true -skin.show_data_tab=true -skin.show_web_api_tab=true -skin.show_r_matlab_tab=true -skin.show_tutorials_tab=true -skin.show_faqs_tab=true -skin.show_tools_tab=true -skin.show_about_tab=true - -# settings controlling the whats new blurb -skin.right_nav.whats_new_blurb=

New data and features released
New tools released

    Sign up for low-volume email news alerts:
    
    Or follow us @cbioportal on Twitter - -# setting controlling the blurb -skin.blurb=The cBioPortal for Cancer Genomics provides visualization, analysis and download of large-scale cancer genomics data sets.

Please adhere to the TCGA publication guidelines when using TCGA data in your publications.

Please cite Gao et al. Sci. Signal. 2013 & Cerami et al. Cancer Discov. 2012 when publishing results based on cBioPortal.

- -# setting controlling the citation below the blurb -# skin.citation_rule_text=Please cite: Cerami et al., 2012 & Gao et al., 2013 - -# setting controlling the footer -skin.footer= | MSKCC | TCGA -# setting controlling listing the development channels in the site's footer section -#skin.footer_show_dev=false - -# setting controlling html for the contact -skin.login.contact_html=If you think you have received this message in error, please contact us at cbioportal-access@cbio.mskcc.org - -# setting controlling the saml registration -skin.login.saml.registration_html=Sign in with MSK - -# settings controlling what to show in the right navigation bar -skin.right_nav.show_data_sets=true -skin.right_nav.show_examples=true -skin.right_nav.show_testimonials=true -skin.right_nav.show_whats_new=true -#skin.right_nav.show_twitter=false - -# settings controlling what to show in the right navigation bar -skin.study_view.link_text=To build your own case set, try out our enhanced Study View. - -# setting controlling the default setting for filtering genes in patient view -# skin.patientview.filter_genes_profiled_all_samples=false - -# settings controlling the appearance of the annotation filter menu in study view and group comparison -# skin.show_settings_menu=false - -# controls the appearance the logout button on a portal with user authentication -# skin.hide_logout_button=false - -# controls whether namespace columns of the MAF file are immediately visible in mutation tables (default is 'false') -# skin.mutation_table.namespace_column.show_by_default=true - -# controls which columns from the mutation tables are immediately visible in mutation tables -# skin.results_view.mutation_table.columns.show_on_init=Sample Id,Protein Change,Annotation,Mutation Type,Copy #,Cosmic,# Mut in Sample -# skin.patient_view.mutation_table.columns.show_on_init=Gene,Protein Change,Annotation,Mutation Type,Copy #,Cosmic,# Mut in Sample -# skin.patient_view.copy_number_table.columns.show_on_init=Gene,CNA,Annotation,Cytoband,Cohort -# skin.patient_view.structural_variant_table.columns.show_on_init=Gene 1,Gene2,Status,Annotation,Variant Class,Event Info,Connection Type - -# setting controlling the home page -## enable this to show studies for which the user does not have permission (will appear greyed out and cannot be analyzed in study view or results view). -# skin.home_page.show_unauthorized_studies=false -## enable this to configure a global message for the studies that are unauthorized; the message can contain placecards like {$.Owner.email} for the studies that have the information in the study tags -# skin.home_page.unauthorized_studies_global_message=The study is unauthorized. You need to request access. -## enable this to show reference genome next to the samples -# skin.home_page.show_reference_genome=false - -## setting controlling whether Download tabs and download/copy-to-clipboard controls should be shown -# skin.hide_download_controls=false - -## setting controlling which name should be used to display the authenticated user (email, or username) -# skin.user_display_name=email - -## enable and set this property to specify a study group to be used to identify public studies for which no specific authorization entries are needed in the `authorities` table -# always_show_study_group= - -## enable expression data in multi-study queries (oncoprint and plots tab) -# true | false | (studies)=>{ return true } -# enable_cross_study_expression= - -## Combined Study View Comparison Limits -# Any Number | Disabled when not set -# studyview.max_samples_selected= - -## change the `-Dauthenticate=` JVM argument to configure -## which method of authentication to use (false, googleplus, social_auth_google, social_auth_microsoft, saml, openid, noauthsessionservice) - -## Should the permissions for groups and users be filtered by this instance's app.name? -## (true means the system only handles "CBIOPORTAL:someGroupPermission" groups, false means "someGroupPermission" works) -filter_groups_by_appname=true -## settings to connect to googleplus/social_auth_google auth infrastructure -googleplus.consumer.key= -googleplus.consumer.secret= - -## settings to connect to social_auth_microsoft auth infrastructure -microsoftlive.consumer.key= -microsoftlive.consumer.secret= - -## SAML settings -# TODO add options for auto- and manual config to docs -# TODO add to docs: metadata-uri can be both URL or metadata xml file -# Providing the SAML2 IDP metadata is sufficient to autoconfigure the provider. The 'metadata-uri' property can point to -# and HTTP endpoint or a metadata xml file on the file system. -#spring.security.saml2.relyingparty.registration.cbio-idp.identityprovider.metadata-uri=classpath:/client-tailored-saml-idp-metadata.xml -spring.security.saml2.relyingparty.registration.cbio-idp.identityprovider.metadata-uri=http://localhost:8082/auth/realms/cbio/protocol/saml/descriptor -spring.security.saml2.relyingparty.registration.cbio-idp.identityprovider.entity-id=http://localhost:8082/auth/realms/cbio -spring.security.saml2.relyingparty.registration.cbio-idp.entity-id=cbioportal -spring.security.saml2.relyingparty.registration.cbio-idp.signing.credentials[0].certificate-location=classpath:/cert.pem -spring.security.saml2.relyingparty.registration.cbio-idp.signing.credentials[0].private-key-location=classpath:/key.pem - -saml.idp.metadata.attribute.email= -saml.idp.metadata.attribute.role= -# TODO document: 'When true, study roles will be retrieved from the cBioPortal database and added to the roles provided by the IDP (default 'false').' -saml.roles-from-database= - -# Change this to configure to configure a custom logout URL: (default: /saml/logout) -saml.logout.url=/saml/logout - -# OAuth2 settings -# Provider information -# A number of wel known IDP are supported as preconfigured CommonOAuth2Providers. -# See: https://docs.spring.io/spring-security/site/docs/5.5.x/reference/html5/#oauth2login-common-oauth2-provider -# For custom IDPs see: https://docs.spring.io/spring-security/site/docs/5.5.x/reference/html5/#oauth2login-custom-provider-properties - -# For OAuth2 Client/Login -# TODO add options for auto- and manual config to docs -# For OIDC clients the issuer-uri is sufficient to autoconfigure the provider (via .well-known endpoint) -spring.security.oauth2.client.provider.cbio-idp.issuer-uri= -spring.security.oauth2.client.provider.cbio-idp.user-name-attribute= -# Configuring the individual settings below is not recommended. - # spring.security.oauth2.client.provider.cbio-idp.authorization-uri= - # spring.security.oauth2.client.provider.cbio-idp.token-uri= - # TODO update docs, the user info endpoint must expose the roles !! - # spring.security.oauth2.client.provider.cbio-idp.user-info-uri= - # spring.security.oauth2.client.provider.cbio-idp.jwk-set-uri= - # spring.security.oauth2.client.provider.cbio-idp.logout-uri= # NOTE: this is not an official property. -spring.security.oauth2.client.registration.cbio-idp.client-id= -spring.security.oauth2.client.registration.cbio-idp.client-secret= -# TODO Can be authorization_code, ... -spring.security.oauth2.client.registration.cbio-idp.authorization-grant-type= -# TODO Can be client_secret_post, ... -spring.security.oauth2.client.registration.cbio-idp.client-authentication-method= -spring.security.oauth2.client.registration.cbio-idp.redirect-uri=/login/oauth2/authorization/ -# Scope must include 'oidc' for SSO logout to work. -spring.security.oauth2.client.registration.cbio-idp.scope=oidc,email,roles -# TODO add to docs (in minutes; default 1) -spring.security.oauth2.allowed-clock-skew= -# TODO add to docs -spring.security.oauth2.logout-url= -saml.sp.metadata.entityid= -# change this url if behind reverse proxy that handles SSL, see docs/Authenticating-Users-via-SAML.md -saml.sp.metadata.entitybaseurl=#{null} -saml.idp.metadata.location= -saml.idp.metadata.entityid= -# saml keystore settings: -saml.keystore.location= -saml.keystore.password= -saml.keystore.private-key.key= -saml.keystore.private-key.password= -saml.keystore.default-key= -# How to send SAML request messages to the IDP. -# Set to "specificBinding" to configure specific binding: -saml.idp.comm.binding.settings=defaultBinding -# Configure the specific binding if above is specificBinding. Leave empty if defaultBinding. -# Options: bindings:HTTP-POST, bindings:HTTP-Redirect, bindings:PAOS, profiles:holder-of-key:SSO:browser -saml.idp.comm.binding.type= -# If true it means that the user will be forced to re-authenticate, even if they have a valid session with the IDP -# it's useful when you don't have control over IDP and the IDP caches user data for to long -# causing cbioportal to CredentialsExpiredException Authentication statement is too old to be used with value -saml.idp.comm.binding.force-auth-n=false -# Change this to configure your custom UserDetails parser (default: org.cbioportal.security.spring.authentication.saml.SAMLUserDetailsServiceImpl) -saml.custom.userservice.class=org.cbioportal.security.spring.authentication.saml.SAMLUserDetailsServiceImpl -# Change this to configure to configure a custom logout URL: (default: /login.jsp?logout_success=true) -saml.logout.url=/login.jsp?logout_success=true - -# data access token settings -dat.unauth_users= -dat.method=none -dat.ttl_seconds=2592000 -dat.uuid.max_number_per_user=1 -dat.jwt.secret_key= -dat.filter_user_role= - -# OAuth2 token data access settings -#dat.oauth2.clientId= -#dat.oauth2.clientSecret= -#dat.oauth2.issuer= -#dat.oauth2.accessTokenUri=/.../token -#dat.oauth2.userAuthorizationUri=/.../auth -#dat.oauth2.jwkUrl=/.../certs -#dat.oauth2.redirectUri=/.../api/data-access-token/oauth2 -#dat.oauth2.jwtRolesPath=resource_access::cbioportal::roles - -# multithreading configuration -multithread.core_pool_size=16 - -# study view settings -# always show studies with this group -always_show_study_group= - -# mdacc heatmap integration -#show.mdacc.heatmap=true - -# patient view settings -patient_view_placeholder=false -digitalslidearchive.iframe.url=http://cancer.digitalslidearchive.net/index_mskcc.php?slide_name= -digitalslidearchive.meta.url=http://cancer.digitalslidearchive.net/local_php/get_slide_list_from_db_groupid_not_needed.php?slide_name_filter= -tumor_image.url=http://cbio.mskcc.org/cancergenomics/tcga-tumor-images/ -tcga_path_report.url=https://github.com/cbioportal/datahub/raw/master/tcga/pathology_reports/pathology_reports.txt - -# various url's -segfile.url=http://cbio.mskcc.org/cancergenomics/gdac-portal/seg/ - - -# The default OncoKB instance, the portal is connecting to, does not include any therapeutic information and the token is not required. -# If you wish to include such information, please consider obtaining a license to support future OncoKB development by following -# https://docs.cbioportal.org/2.4-integration-with-other-webservices/oncokb-data-access. - -# Enable OncoKB annotation (true, false) -show.oncokb=true - -# The URL of the OncoKB instance to connect to. -# The default address does not require authentication and is freely to use. -oncokb.public_api.url=https://public.api.oncokb.org/api/v1 - -# Your OncoKB Token which an be found under https://www.oncokb.org/account/settings -oncokb.token= - -# Enable merging of OncoKB icons by default -# oncokb.merge_icons_by_default=true - -# Enable "cBioPortal>=" driver annotation sources in the settings menu of Results View (true, false) -show.cbioportal=true -# Enable "COSMIC>=" driver annotation sources in the settings menu of Results View (true, false) -show.cosmic=true - -# Enable Chang's hotspot list (true, false) -show.hotspot=true - -# Enable Civic variant annotation (true, false) -show.civic=false - -# Link to My Cancer Genome. Please disable (set to false) when using cBioPortal with patient identifiable data due My Cancer Genome license restrictions. -mycancergenome.show=true - -# Enable transcript switch dropdown (true, false) -# show.transcript_dropdown=false - -# Show/hide p- and q-values in survival types table (default is true) -# survival.show_p_q_values_in_survival_type_table=false - -# Set initial x-axis limit for survival plot (by default, initial limit will be the latest event in the data) -# survival.initial_x_axis_limit=120 - -# Set Genome Nexus annotation sources, please list all sources name with comma-separated. -# Available sources: mutation_assessor -# show.genomenexus.annotation_sources=mutation_assessor - -# Choose Genome Nexus default set of isoforms. Read more at -# https://docs.cbioportal.org. (Options are uniprot or mskcc, default is mskcc) -# genomenexus.isoform_override_source=mskcc - -# Enable SIGNAL column in mutations table(true, false) -# show.signal=false - -# Enable NDex pathways integration (true, false) -# show.ndex=false - -# igv bam linking -igv.bam.linking= -# colon delimited -igv.bam.linking.studies= -openssl.binary= -signature.key= -encryption.key= -broad.bam.url= -broad.bam.checking.url= - -# pathway settings -include_networks=true -pathway_commons.url=http://www.pathwaycommons.org/pc2 - -# the new API uses the v3 of bitly API, and a java library to make the API call, so you only need to provide the access token -bitly.access.token= - -# google analytics -google_analytics_profile_id= - -# genomespace linking -genomespace=true - -# session-service url: http://[host]:[port]/[session_service_app]/api/sessions/[portal_instance]/ -# example session-service url: http://localhost:8080/session_service/api/sessions/public_portal/ -# see: https://github.com/cBioPortal/session-service -# excluding this value or setting it to an empty string will revert to the previous bookmarking method -# WARNING: do not use session service with -Dauthenticate=false -# either use authentication or change to -Dauthenticate=noauthsessionservice -session.service.url= -# if basic authentication is enabled on session service one should set: -# session.service.user=user -# session.service.password=pass - -# disabled tabs, | delimited -# possible values: cancer_types_summary, mutual_exclusivity, comparison, plots, mutations, co_expression, enrichments, survival, network, download, bookmark, IGV -disabled_tabs= - -# study ids and categories to force to top of study selector -# format is category1#study1a,study1b,study1c;category2#study2 -priority_studies= - -# species and genomic information -species=human -ncbi.build=37 -ucsc.build=hg19 - -# default view in oncoprint (sample, patient (default)) -oncoprint.defaultview=patient - -# OncoPrint driver mutation annotations -# oncoprint.custom_driver_annotation.binary.menu_label=Custom driver annotation -# oncoprint.custom_driver_annotation.tiers.menu_label=Custom driver tiers -# oncoprint.custom_driver_annotation.binary.default=true -# oncoprint.custom_driver_annotation.tiers.default=true -oncoprint.oncokb.default=true -oncoprint.hotspots.default=true -# oncoprint.hide_vus.default=true -# oncoprint.clinical_tracks.config_json=classpath:/oncoprint-default-tracks.json -# oncoprint.clustered.default=true - -# Custom gene sets -# querypage.setsofgenes.location=file:/ - -# valid cache types are (ehcache-heap, ehcache-disk, ehcache-hybrid, redis), or use 'no-cache' to disable caching -# caution 1: the 'redis' caching option will likely cause a conflict when installing the portal in a tomcat installation which uses redisson for session management -# caution 2: this configuration needs to be set both at compile time and run time. See also https://github.com/cBioPortal/cbioportal/issues/8629 -persistence.cache_type=no-cache -# Enable cache statistics endpoint for cache monitoring -#cache.statistics_endpoint_enabled=false -# Turn cache management endpoint on or off (default) -# cache.endpoint.enabled=true -# API key for access to cache management endpoint -# cache.endpoint.api-key=fd15f1ae-66f2-4b8a-8d54-fb899b03557e -# Externalize the study data used for user authorization evaluation to Spring-managed caches such as EHCache or Redis. -# Enabling this might simplify cache-invalidation strategies (via /api/cache endpoint) because it allows for invalidation -# a central caching solution shared among cBioPortal containers in a single instance. It comes at the cost of extra calls -# to the caching provider. Default is 'false' meaning that cBioPortal will use a faster local HashMap-based cache for fast -# lookup of sample/patient/profile to cancer study relationships. -#cache.cache-map-utils.spring-managed=false - -# Redis properties -# Unique name for each portal instance, used for distinguishing caches -#redis.name= -#redis.leader_address= -#redis.follower_address= -#redis.database= -#redis.password= -#redis.ttl_mins=10000 -#redis.clear_on_startup=true - -# Ehcache properties -#ehcache.xml_configuration=/ehcache.xml - -# Properties for specifying cache size constraints -# - Zero is not an accepted value, will break deployment -# - disk size (if used) must be greater than heap size - -#ehcache.general_repository_cache.max_mega_bytes_heap=1024 -#ehcache.static_repository_cache_one.max_mega_bytes_heap=30 - -#ehcache.persistence_path=/tmp -#ehcache.general_repository_cache.max_mega_bytes_local_disk=4096 -#ehcache.static_repository_cache_one.max_mega_bytes_local_disk=32 - -# Default cross cancer study query -# query this session id when not specifying a study for -# linkout links e.g. /ln?q=TP53:MUT or when querying a single gene in quick -# search -# -# default_cross_cancer_study_session_id= -# -# if session service is not enabled, specify a comma separated list of studies -# here instead e.g.: -# -# default_cross_cancer_study_list=mixed_pipseq_2017,cellline_nci60 -# default_cross_cancer_study_list_name=My list of studies - -# Enable/Disable quick search (currently in beta, default is false) -# quick_search.enabled=true - -# enable/disable hrrs logging -# hrrs can be used for debugging - when enabled incoming web requests -# will be logged into the specified directory -# logs must be decrypted for more in-depth information -# see: https://github.com/vy/hrrs/blob/master/README.md -#hrrs.logging.filepath= -#hrrs.enable.logging=false - -# enable/disable aspectj logging -# if active, all enter/exits to methods in web, service-impl, -# and mybatis packages are logged -#aspect.enable.logging=false - -# ensembl URL template for transcript lookup in Mutations tab. Default is http://grch37.ensembl.org/homo_sapiens/Transcript/Summary?t=<%= transcriptId %> -#ensembl.transcript_url=http://ensembl.org/homo_sapiens/Transcript/Summary?t=<%= transcriptId %> - -# Enable/disable Persistent Cache (true, false) -# The Persistent Cache is a frontend feature that is used to cache semi static -# data produced by APIs. It uses IndexedDB as a means for persistent storage. -# This feature is disabled by default. -# enable_persistent_cache=true - -# Limit the size of gene queries (number). gene count * sample count < query_product_limit -# This limit is enforced on the frontend. -# query_product_limit=1000000 - -# Limit the size of samples in clinical tab in study view page. clinical attribute count * sample count < clinical_attribute_product_limit -# This limit is enforced on the frontend. -# clinical_attribute_product_limit=6500000 - -# Enable gsva to query -# skin.show_gsva=true -# Set default thresholds for geneset hierarchy -# skin.geneset_hierarchy.default_gsva_score=0.5 -# skin.geneset_hierarchy.default_p_value=0.05 -# Collapse the tree widget of the gsva hierarchy dialog on init -# skin.geneset_hierarchy.collapse_by_default=true - -# Compress some particularly large request bodies. enable_request_body_gzip_compression enables the feature, and -# request_gzip_body_size_bytes sets the maximum allowable uncompressed request body size in bytes. Requests larger than -# this value will be rejected. If unset, the default value will be 50000000, or 50 Mb. -# enable_request_body_gzip_compression=true -# request_gzip_body_size_bytes=80000000 - -# Installation map URL for installation map iframes. -# If blank or commented out, no map will be shown and that page will be hidden. -# installation_map_url=https://installationmap.netlify.app/ - -# Feature flag for treatment groups -# enable_treatment_groups=false - -# Set comparison categorical "NA" value (not case sensitive), separated by "|" -# comparison.categorical_na_values=NA|unknown - -# Set StudyDownloadLinkUrl -# Allows download links within DataSets Tab (See Portal.Properties documentation for more info) -# study_download_url= - -# download_group= - -# vaf.sequential_mode.default=false -# vaf.log_scale.default=false diff --git a/src/main/resources/security.properties.EXAMPLE b/src/main/resources/security.properties.EXAMPLE index fdedb60d6bb..57fcc31447d 100644 --- a/src/main/resources/security.properties.EXAMPLE +++ b/src/main/resources/security.properties.EXAMPLE @@ -80,4 +80,8 @@ dat.filter_user_role= always_show_study_group=PUBLIC ## Should the permissions for groups and users be filtered by this instance's app.name? ## (true means the system only handles "CBIOPORTAL:someGroupPermission" groups, false means "someGroupPermission" works) -filter_groups_by_appname=false \ No newline at end of file +filter_groups_by_appname=false + +## CORS Configuration (Disabled by default) +# To Enable CORS uncomment and set the allowed-origins urls. comma delimited. To enable all origins use * +#security.cors.allowed-origins=* \ No newline at end of file diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html index 9d66dee157b..669fd57cc21 100644 --- a/src/main/resources/templates/login.html +++ b/src/main/resources/templates/login.html @@ -42,7 +42,7 @@

You are not authorized to access this resource.  - +

diff --git a/src/main/resources/templates/restful_login.html b/src/main/resources/templates/restful_login.html new file mode 100644 index 00000000000..ec9ea536623 --- /dev/null +++ b/src/main/resources/templates/restful_login.html @@ -0,0 +1,43 @@ + + + + + + + +
+ + + + + + + + + + + + + +
+
+
+ +
+
+
+
+

Connecting to the MSK cBioPortal...

+
+
loading
+
+
+
+
+ + \ No newline at end of file diff --git a/src/main/resources/webapp/config_service.jsp b/src/main/resources/webapp/config_service.jsp index d2b1ce2bee9..e4e6baf8b7f 100644 --- a/src/main/resources/webapp/config_service.jsp +++ b/src/main/resources/webapp/config_service.jsp @@ -133,7 +133,7 @@ JSONObject obj = new JSONObject(); - // for each above, add json prop and lookup value in portal.properties + // for each above, add json prop and lookup value in application.properties for (int i = 0; i < propNameArray.length; i++){ String value = GlobalProperties.getProperty(propNameArray[i]); diff --git a/src/main/resources/webapp/jsp/civic/civic-qtip-template.html b/src/main/resources/webapp/jsp/civic/civic-qtip-template.html deleted file mode 100644 index 1f87389d9b7..00000000000 --- a/src/main/resources/webapp/jsp/civic/civic-qtip-template.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - - diff --git a/src/main/resources/webapp/jsp/co_expression.jsp b/src/main/resources/webapp/jsp/co_expression.jsp deleted file mode 100644 index a4dc16c0837..00000000000 --- a/src/main/resources/webapp/jsp/co_expression.jsp +++ /dev/null @@ -1,57 +0,0 @@ -<%-- -- Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. -- -- This library is distributed in the hope that it will be useful, but WITHOUT -- ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS -- FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder -- is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no -- obligations to provide maintenance, support, updates, enhancements or -- modifications. In no event shall Memorial Sloan-Kettering Cancer Center be -- liable to any party for direct, indirect, special, incidental or -- consequential damages, including lost profits, arising out of the use of this -- software and its documentation, even if Memorial Sloan-Kettering Cancer -- Center has been advised of the possibility of such damage. ---%> - -<%-- -- This file is part of cBioPortal. -- -- cBioPortal is free software: you can redistribute it and/or modify -- it under the terms of the GNU Affero General Public License as -- published by the Free Software Foundation, either version 3 of the -- License. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU Affero General Public License for more details. -- -- You should have received a copy of the GNU Affero General Public License -- along with this program. If not, see . ---%> -
- - \ No newline at end of file diff --git a/src/main/resources/webapp/jsp/cross_cancer_plots_tab.jsp b/src/main/resources/webapp/jsp/cross_cancer_plots_tab.jsp deleted file mode 100644 index a303a76a04f..00000000000 --- a/src/main/resources/webapp/jsp/cross_cancer_plots_tab.jsp +++ /dev/null @@ -1,71 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - - - - -
- -
- - - diff --git a/src/main/resources/webapp/jsp/data_download.jsp b/src/main/resources/webapp/jsp/data_download.jsp deleted file mode 100644 index ff0f3ac4556..00000000000 --- a/src/main/resources/webapp/jsp/data_download.jsp +++ /dev/null @@ -1,79 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.model.GeneWithScore" %> -<%@ page import="org.mskcc.cbio.portal.util.ValueParser" %> -<%@ page import="java.util.TreeSet" %> -<%@ page import="org.mskcc.cbio.portal.model.DownloadLink" %> -<%@ page import="java.util.ArrayList" %> -<%@ page import="org.mskcc.cbio.portal.servlet.QueryBuilder" %> - -
-
- - - - -<% - String debugStr = request.getParameter("xdebug"); - boolean debug = false; - if (debugStr != null && debugStr.equals("1")) { - debug = true; - } - String textOnly = request.getParameter("text_only"); -%> diff --git a/src/main/resources/webapp/jsp/enrichments_tab.jsp b/src/main/resources/webapp/jsp/enrichments_tab.jsp deleted file mode 100644 index 8a0304717ec..00000000000 --- a/src/main/resources/webapp/jsp/enrichments_tab.jsp +++ /dev/null @@ -1,29 +0,0 @@ -
- - \ No newline at end of file diff --git a/src/main/resources/webapp/jsp/error.jsp b/src/main/resources/webapp/jsp/error.jsp deleted file mode 100644 index d2cade6da30..00000000000 --- a/src/main/resources/webapp/jsp/error.jsp +++ /dev/null @@ -1,65 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.servlet.QueryBuilder" %> -<%@ page import="org.mskcc.cbio.portal.util.GlobalProperties" %> -<% - request.setAttribute(QueryBuilder.HTML_TITLE, "cBio Cancer Genomics Pathway Portal::Error"); - String userMessage = (String) request.getAttribute(QueryBuilder.USER_ERROR_MESSAGE); - String emailContact = (userMessage != null && userMessage.contains("not authorized")) ? - "cbioportal-access at cbio dot mskcc dot org" : GlobalProperties.getEmailContact(); -%> - - -
-

- <% if (userMessage != null) { %> - Oops! <%= userMessage %>

- <% } else {%> - Oops! An Error Has occurred while processing your request. - <% } %> -  Please try again or send email to <%= emailContact %> if this is any error in this portal. -
- - - - - - - - - - - - - - diff --git a/src/main/resources/webapp/jsp/global/css_include.jsp b/src/main/resources/webapp/jsp/global/css_include.jsp deleted file mode 100644 index 76a56f5b033..00000000000 --- a/src/main/resources/webapp/jsp/global/css_include.jsp +++ /dev/null @@ -1,76 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.util.GlobalProperties" %> -<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core' %> - - - - - - - - - - - - - - - -" type="text/css" rel="stylesheet"/> - - - - - - -<% - String authenticationMethod = GlobalProperties.authenticationMethod(); - String global_style = GlobalProperties.getProperty("global_css"); - String special_style = GlobalProperties.getProperty("special_css"); - if (global_style == null) { - global_style = "css/global_portal.css?"+GlobalProperties.getAppVersion(); - } else { - global_style = "css/" + global_style+"?"+GlobalProperties.getAppVersion(); - } - if (special_style != null) { - special_style = "css/" + special_style+"?"+GlobalProperties.getAppVersion(); - } - String globalStyleCSSPath = (authenticationMethod.equals("saml") || authenticationMethod.equals("saml_plus_basic")) ? - "/" + global_style : global_style; - pageContext.setAttribute("globalStyleCSSPath", globalStyleCSSPath); -%> -" type="text/css" rel="stylesheet" /> -<% if (special_style != null) { %> - -<% } %> diff --git a/src/main/resources/webapp/jsp/global/css_include_standard.jsp b/src/main/resources/webapp/jsp/global/css_include_standard.jsp deleted file mode 100644 index b21cfe1f536..00000000000 --- a/src/main/resources/webapp/jsp/global/css_include_standard.jsp +++ /dev/null @@ -1,65 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.util.GlobalProperties" %> - - - - - - - - - - - - - - - - -<% - String global_style = GlobalProperties.getProperty("global_css"); - String special_style = GlobalProperties.getProperty("special_css"); - if (global_style == null) { - global_style = "css/global_portal.css?"+GlobalProperties.getAppVersion(); - } else { - global_style = "css/" + global_style+"?"+GlobalProperties.getAppVersion(); - } - if (special_style != null) { - special_style = "css/" + special_style+"?"+GlobalProperties.getAppVersion(); - } -%> - -<% if (special_style != null) { %> - -<% } %> diff --git a/src/main/resources/webapp/jsp/global/footer.jsp b/src/main/resources/webapp/jsp/global/footer.jsp deleted file mode 100644 index 0185da1a410..00000000000 --- a/src/main/resources/webapp/jsp/global/footer.jsp +++ /dev/null @@ -1,31 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> diff --git a/src/main/resources/webapp/jsp/global/frontend_config.jsp b/src/main/resources/webapp/jsp/global/frontend_config.jsp deleted file mode 100644 index 59e5a748c22..00000000000 --- a/src/main/resources/webapp/jsp/global/frontend_config.jsp +++ /dev/null @@ -1,123 +0,0 @@ -<%@ page import="java.util.List" %> -<%@ page import="org.mskcc.cbio.portal.servlet.CheckDarwinAccessServlet" %> -<%@ page import="org.mskcc.cbio.portal.util.GlobalProperties" %> - - diff --git a/src/main/resources/webapp/jsp/global/global_variables.jsp b/src/main/resources/webapp/jsp/global/global_variables.jsp deleted file mode 100644 index 70c0dcba21a..00000000000 --- a/src/main/resources/webapp/jsp/global/global_variables.jsp +++ /dev/null @@ -1,159 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - - - -<%@ include file="src/main/webapp/jsp/global/selected_study_variables.jsp" %> - -<%@ page import="org.mskcc.cbio.portal.servlet.QueryBuilder" %> -<%@ page import="java.util.ArrayList" %> -<%@ page import="java.util.HashSet" %> -<%@ page import="org.mskcc.cbio.portal.model.*" %> -<%@ page import="java.text.NumberFormat" %> -<%@ page import="java.text.DecimalFormat" %> -<%@ page import="java.util.Set" %> -<%@ page import="java.util.*" %> -<%@ page import="java.util.Iterator" %> -<%@ page import="org.mskcc.cbio.portal.servlet.ServletXssUtil" %> -<%@ page import="java.util.Enumeration" %> -<%@ page import="java.net.URLEncoder" %> -<%@ page import="org.mskcc.cbio.portal.oncoPrintSpecLanguage.CallOncoPrintSpecParser" %> -<%@ page import="org.mskcc.cbio.portal.oncoPrintSpecLanguage.ParserOutput" %> -<%@ page import="org.mskcc.cbio.portal.oncoPrintSpecLanguage.OncoPrintSpecification" %> -<%@ page import="org.mskcc.cbio.portal.oncoPrintSpecLanguage.Utilities" %> -<%@ page import="org.mskcc.cbio.portal.model.CancerStudy" %> -<%@ page import="org.mskcc.cbio.portal.model.SampleList" %> -<%@ page import="org.mskcc.cbio.portal.model.GeneticProfile" %> -<%@ page import="org.mskcc.cbio.portal.model.GeneticAlterationType" %> -<%@ page import="org.mskcc.cbio.portal.model.Patient" %> -<%@ page import="org.mskcc.cbio.portal.dao.DaoGeneticProfile" %> -<%@ page import="org.apache.commons.logging.LogFactory" %> -<%@ page import="org.apache.commons.logging.Log" %> -<%@ page import="org.apache.commons.text.StringEscapeUtils" %> -<%@ page import="java.lang.reflect.Array" %> -<%@ page import="org.mskcc.cbio.portal.util.*" %> -<%@ page import="org.mskcc.cbio.portal.dao.DaoMutation" %> - -<%@include file="src/main/webapp/jsp/global/server_vars.jsp"%> -<% - Boolean showIGVtab = (Boolean) request.getAttribute("showIGVtab"); - Boolean has_mrna = (Boolean) request.getAttribute("hasMrna"); - Boolean has_methylation = (Boolean) request.getAttribute("hasMethylation"); - Boolean has_copy_no = (Boolean) request.getAttribute("hasCopyNo"); - Boolean has_survival = (Boolean) request.getAttribute("hasSurvival"); - boolean includeNetworks = GlobalProperties.includeNetworks(); - boolean computeLogOddsRatio = true; - Boolean mutationDetailLimitReached = (Boolean)request.getAttribute(QueryBuilder.MUTATION_DETAIL_LIMIT_REACHED); - boolean showCoexpTab = false; - - //are we using session service for bookmarking? - boolean useSessionServiceBookmark = !StringUtils.isBlank(GlobalProperties.getSessionServiceUrl()); - - //General site info - String siteTitle = GlobalProperties.getTitle(); - - request.setAttribute(QueryBuilder.HTML_TITLE, siteTitle+"::Results"); - - //check if show co-expression tab - if(!isVirtualStudy){ - GeneticProfile final_gp = CoExpUtil.getPreferedGeneticProfile(StudiesMap.keySet().iterator().next()); - if (final_gp != null) { - showCoexpTab = true; - } - } -%> - - - - - - - - - - - -<%! - public int countProfiles (ArrayList profileList, GeneticAlterationType type) { - int counter = 0; - for (int i = 0; i < profileList.size(); i++) { - GeneticProfile profile = profileList.get(i); - if (profile.getGeneticAlterationType() == type) { - counter++; - } - } - return counter; - } -%> diff --git a/src/main/resources/webapp/jsp/global/header.jsp b/src/main/resources/webapp/jsp/global/header.jsp deleted file mode 100644 index 1d16ef2e06b..00000000000 --- a/src/main/resources/webapp/jsp/global/header.jsp +++ /dev/null @@ -1,79 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> -<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> - -<%@ page import="org.mskcc.cbio.portal.servlet.QueryBuilder" %> -<%@ page import="org.mskcc.cbio.portal.util.GlobalProperties" %> - -<%if(request.getAttribute("standard-js-css")!=null){%> - - -<%} else {%> - - -<%}%> - - - - - <%= request.getAttribute(QueryBuilder.HTML_TITLE)%> - - -
-
-
- -
-
- - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/webapp/jsp/patient_view/drugs.jsp b/src/main/resources/webapp/jsp/patient_view/drugs.jsp deleted file mode 100644 index e1efd3923aa..00000000000 --- a/src/main/resources/webapp/jsp/patient_view/drugs.jsp +++ /dev/null @@ -1,261 +0,0 @@ -<%-- - - Copyright (c) 2015 - 2016 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%-- - ~ Copyright (c) 2012 Memorial Sloan-Kettering Cancer Center. - ~ This library is free software; you can redistribute it and/or modify it - ~ under the terms of the GNU Lesser General Public License as published - ~ by the Free Software Foundation; either version 2.1 of the License, or - ~ any later version. - ~ - ~ This library is distributed in the hope that it will be useful, but - ~ WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF - ~ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. The software and - ~ documentation provided hereunder is on an "as is" basis, and - ~ Memorial Sloan-Kettering Cancer Center - ~ has no obligations to provide maintenance, support, - ~ updates, enhancements or modifications. In no event shall - ~ Memorial Sloan-Kettering Cancer Center - ~ be liable to any party for direct, indirect, special, - ~ incidental or consequential damages, including lost profits, arising - ~ out of the use of this software and its documentation, even if - ~ Memorial Sloan-Kettering Cancer Center - ~ has been advised of the possibility of such damage. See - ~ the GNU Lesser General Public License for more details. - ~ - ~ You should have received a copy of the GNU Lesser General Public License - ~ along with this library; if not, write to the Free Software Foundation, - ~ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - --%> - - - - -
- -
-
diff --git a/src/main/resources/webapp/jsp/global/header_bar.jsp b/src/main/resources/webapp/jsp/global/header_bar.jsp deleted file mode 100644 index a6eaf1510d8..00000000000 --- a/src/main/resources/webapp/jsp/global/header_bar.jsp +++ /dev/null @@ -1,237 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.util.GlobalProperties" %> -<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core' %> -<%@ taglib prefix="s" uri="http://www.springframework.org/tags" %> -<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> -<% - String principal = ""; - String authenticationMethod = GlobalProperties.authenticationMethod(); - pageContext.setAttribute("authenticationMethod", authenticationMethod); - if (authenticationMethod.equals("openid") || authenticationMethod.equals("ldap")) { - principal = "principal.name"; - } - else if (authenticationMethod.equals("googleplus") || - authenticationMethod.equals("saml") || - authenticationMethod.equals("ad") || - authenticationMethod.contains("social_auth") || - authenticationMethod.equals("saml_plus_basic")) { - principal = "principal.username"; - } - pageContext.setAttribute("principal", principal); -%> -<%-- Calling static methods is not supported in all versions of EL without - explicitly defining a function in an external taglib XML file. Using - Spring's SpEL instead to keep it short for this one function call --%> - - - - - - - - - - - -
-
- - - -
- -
- <%-- Display Sign Out Button for Real (Non-Anonymous) User --%> - -
Logged in as  |  - - - Sign out - - - Sign out - - -
-
- - <% if (authenticationMethod.contains("social_auth")) { %> - - -
-   - -    -
-
- - <% } %> - - - - - " alt="Institute Logo" /> - -
- -
- - - diff --git a/src/main/resources/webapp/jsp/global/js_include.jsp b/src/main/resources/webapp/jsp/global/js_include.jsp deleted file mode 100644 index c99baa2bded..00000000000 --- a/src/main/resources/webapp/jsp/global/js_include.jsp +++ /dev/null @@ -1,107 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.util.GlobalProperties" %> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<%----> - - -<%-- - - - ---%> - - - - - - - - - - - - - - - - - - - - - -<%--The 3 files make expression tab work--%> - - - \ No newline at end of file diff --git a/src/main/resources/webapp/jsp/global/js_include_analytics_and_email.jsp b/src/main/resources/webapp/jsp/global/js_include_analytics_and_email.jsp deleted file mode 100644 index 62d732b84ee..00000000000 --- a/src/main/resources/webapp/jsp/global/js_include_analytics_and_email.jsp +++ /dev/null @@ -1,61 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.util.GlobalProperties" %> - -<% -String googleAnalyticsProfileId = GlobalProperties.getGoogleAnalyticsProfileId(); -if (googleAnalyticsProfileId!=null && !googleAnalyticsProfileId.isEmpty()) { -%> - - - - -<% } %> - - - diff --git a/src/main/resources/webapp/jsp/global/js_include_standard.jsp b/src/main/resources/webapp/jsp/global/js_include_standard.jsp deleted file mode 100644 index a1fe536a1c7..00000000000 --- a/src/main/resources/webapp/jsp/global/js_include_standard.jsp +++ /dev/null @@ -1,64 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.util.GlobalProperties" %> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/webapp/jsp/global/legacy_head.jsp b/src/main/resources/webapp/jsp/global/legacy_head.jsp deleted file mode 100644 index e5524d201d7..00000000000 --- a/src/main/resources/webapp/jsp/global/legacy_head.jsp +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/main/resources/webapp/jsp/global/right_column.jsp b/src/main/resources/webapp/jsp/global/right_column.jsp deleted file mode 100644 index 353fb778826..00000000000 --- a/src/main/resources/webapp/jsp/global/right_column.jsp +++ /dev/null @@ -1,94 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.util.GlobalProperties" %> -<%@ page import="org.mskcc.cbio.portal.util.DataSetsUtil" %> -<%@ page import="org.mskcc.cbio.portal.model.CancerStudyStats" %> -<%@ page import="java.util.List" %> -<%@ page import="java.util.ArrayList" %> - - - -
- - - - - - <% if (GlobalProperties.showRightNavDataSets()) { %> - - <% } %> - -<% if (GlobalProperties.showRightNavExamples()) {%> - -<% } %> - -<% if (GlobalProperties.showRightNavTestimonials()) {%> - -<% } %> -
diff --git a/src/main/resources/webapp/jsp/global/selected_study_variables.jsp b/src/main/resources/webapp/jsp/global/selected_study_variables.jsp deleted file mode 100644 index 42edd65b300..00000000000 --- a/src/main/resources/webapp/jsp/global/selected_study_variables.jsp +++ /dev/null @@ -1,34 +0,0 @@ -<%@page import="java.util.stream.Collectors"%> -<%@page import="com.fasterxml.jackson.databind.ObjectMapper"%> -<%@page import="java.util.Set"%> -<%@page import="java.util.HashMap"%> -<%@page import="com.fasterxml.jackson.core.type.TypeReference"%> -<%@ page import="org.mskcc.cbio.portal.servlet.QueryBuilder" %> - -<% - String cancerStudyId = (String)request.getAttribute(QueryBuilder.CANCER_STUDY_ID); - String cancerStudyIdListStr = (String)request.getAttribute(QueryBuilder.CANCER_STUDY_LIST); - - TypeReference>> typeRef = new TypeReference>>() {}; - ObjectMapper mapper = new ObjectMapper(); - HashMap> StudiesMap = new HashMap>(); - if((String)request.getAttribute("STUDY_SAMPLE_MAP") != null) - StudiesMap = mapper.readValue((String)request.getAttribute("STUDY_SAMPLE_MAP"), typeRef); - - //consider virtual study with one real study as regular study and show all the tabs if caseSetId is -1 - String _sampleSetId = (String) request.getAttribute(QueryBuilder.CASE_SET_ID); - Boolean isVirtualStudy = StudiesMap.size() > 1; - if(StudiesMap.size() == 1 && cancerStudyIdListStr != null && cancerStudyIdListStr.split(",").length>1 && !_sampleSetId.equals("-1")){ - isVirtualStudy = true; - } - - String normalizedCancerStudyIdListStr = StudiesMap.keySet().stream().collect(Collectors.joining(",")); - pageContext.setAttribute("normalizedCancerStudyIdListStr", normalizedCancerStudyIdListStr); -%> - diff --git a/src/main/resources/webapp/jsp/global/server_vars.jsp b/src/main/resources/webapp/jsp/global/server_vars.jsp deleted file mode 100644 index c809a3fa9b5..00000000000 --- a/src/main/resources/webapp/jsp/global/server_vars.jsp +++ /dev/null @@ -1,103 +0,0 @@ -<%@ page import="org.mskcc.cbio.portal.servlet.ServletXssUtil" %> -<%@ page import="org.mskcc.cbio.portal.util.XssRequestWrapper" %> -<%@ page import="java.util.HashSet" %> -<%@ page import="org.mskcc.cbio.portal.servlet.QueryBuilder" %> -<%@ page import="org.apache.commons.lang3.StringUtils" %> -<% - //Security Instance - ServletXssUtil xssUtil = ServletXssUtil.getInstance(); - - //Info about Genetic Profiles - HashSet geneticProfileIdSet = (HashSet) request.getAttribute(QueryBuilder.GENETIC_PROFILE_IDS); - String geneticProfiles = StringUtils.join(geneticProfileIdSet.iterator(), " "); - geneticProfiles = xssUtil.getCleanerInput(geneticProfiles.trim()); - - //Info about threshold settings - String zScoreThreshold = String.valueOf(request.getAttribute(QueryBuilder.Z_SCORE_THRESHOLD)); - String rppaScoreThreshold = String.valueOf(request.getAttribute(QueryBuilder.RPPA_SCORE_THRESHOLD)); - - //Onco Query Language Parser Instance - String oql = request.getParameter(QueryBuilder.GENE_LIST); - if (request instanceof XssRequestWrapper) { - oql = ((XssRequestWrapper)request).getRawParameter(QueryBuilder.GENE_LIST); - } - oql = xssUtil.getCleanerInput(oql); - - // List of queried gene sets - String genesetIds = request.getParameter(QueryBuilder.GENESET_LIST); - - String studySampleMapJson = (String)request.getAttribute("STUDY_SAMPLE_MAP"); - String sampleSetId = (String) request.getAttribute(QueryBuilder.CASE_SET_ID); - String sampleSetName = request.getAttribute("case_set_name") != null ? (String) request.getAttribute("case_set_name") : "User-defined Patient List"; - String sampleSetDescription = request.getAttribute("case_set_description") != null ? (String) request.getAttribute("case_set_description") : "User-defined Patient List."; - String sampleIdsKey = request.getAttribute(QueryBuilder.CASE_IDS_KEY) != null ? (String) request.getAttribute(QueryBuilder.CASE_IDS_KEY) : ""; - - String caseIds = (String) request.getAttribute(QueryBuilder.CASE_IDS); - if (request.getAttribute(QueryBuilder.CASE_IDS) != null) { - caseIds = caseIds.replace("\n","+"); - } - - sampleSetName = sampleSetName.replaceAll("'", "\\'"); - sampleSetName = sampleSetName.replaceAll("\"", "\\\""); - - Integer dataPriority = (Integer) request.getAttribute(QueryBuilder.DATA_PRIORITY); -%> - - diff --git a/src/main/resources/webapp/jsp/global/small_onco_print_legend.jsp b/src/main/resources/webapp/jsp/global/small_onco_print_legend.jsp deleted file mode 100644 index f4b65058f1e..00000000000 --- a/src/main/resources/webapp/jsp/global/small_onco_print_legend.jsp +++ /dev/null @@ -1,41 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -
-amplified-notShown-normal.png -Amplification -homoDeleted-notShown-normal.png -Deep Deletion -diploid-notShown-mutated.png -Mutation -
Copy number alterations are putative.
-
diff --git a/src/main/resources/webapp/jsp/global/xdebug.jsp b/src/main/resources/webapp/jsp/global/xdebug.jsp deleted file mode 100644 index 1baa0f74eda..00000000000 --- a/src/main/resources/webapp/jsp/global/xdebug.jsp +++ /dev/null @@ -1,160 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.util.XDebug" %> -<%@ page import="org.mskcc.cbio.portal.util.XDebugParameter" %> -<%@ page import="java.util.Enumeration" %> -<%@ page import="java.util.Date" %> -<%@ page import="java.util.ArrayList" %> -<%@ page import="org.mskcc.cbio.portal.util.XDebugMessage" %> -<% - XDebug xdebug = (XDebug) request.getAttribute("xdebug_object"); - if (xdebug != null) { - xdebug.stopTimer(); - Enumeration enum0 = request.getAttributeNames(); - while (enum0.hasMoreElements()) { - String name = (String) enum0.nextElement(); - Object value = request.getAttribute(name); - xdebug.addParameter(XDebugParameter.REQUEST_ATTRIBUTE_TYPE, name, - value.toString()); - } -%> -<% - String xdebugParameter = request.getParameter("xdebug"); - if (xdebugParameter != null) { -%> - - - - - - - - - - - - - - - <%-- - *********************************** - Output Log Messages - *********************************** - --%> - <% - ArrayList messages = xdebug.getDebugMessages(); - for (int msgIndex = 0; msgIndex < messages.size(); msgIndex++) { - XDebugMessage msg = (XDebugMessage) messages.get(msgIndex); - %> - - - - - <% } %> - <%-- - *********************************** - Output Parameter Values - *********************************** - --%> - - - - - - <% - ArrayList parameters = xdebug.getParameters(); - String bgcolor; - for (int paramIndex=0; paramIndex - - - - - - - <% } %> -
- Total Time to Generate Page - - <%= xdebug.getTimeElapsed() %> ms -
- Current Time - - <%= new Date() %> ms -
- Class Name - - Message -
- <%= wrapText(msg.getClassName()) %> - - - <%= wrapText(msg.getMessage()) %> - -
Parameter TypeNameValue
<%= wrapText(param.getTypeName()) %><%= wrapText(param.getName()) %><%= wrapText(param.getValue()) %>
-<% } %> -<% } %> - -<%! - -// This is a little hack to replace .'s with .'s followed by a zero-width spacer. -// Enables browsers to wrap long words within tables -private String wrapText (String text) { - if (text != null) { - text = text.replaceAll("\\.", "\\. "); - text = text.replaceAll("&", "&"); - return text; - } else { - return new String ("Not Available"); - } -} -%> diff --git a/src/main/resources/webapp/jsp/igv.jsp b/src/main/resources/webapp/jsp/igv.jsp deleted file mode 100644 index 95f3473cce1..00000000000 --- a/src/main/resources/webapp/jsp/igv.jsp +++ /dev/null @@ -1,58 +0,0 @@ -<%-- - - Copyright (c) 2015 - 2016 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - - -
\ No newline at end of file diff --git a/src/main/resources/webapp/jsp/linkoutRedirect.jsp b/src/main/resources/webapp/jsp/linkoutRedirect.jsp deleted file mode 100644 index c77ff39ad17..00000000000 --- a/src/main/resources/webapp/jsp/linkoutRedirect.jsp +++ /dev/null @@ -1,21 +0,0 @@ -<%-- - Created by IntelliJ IDEA. - User: suny1 - Date: 6/15/16 - Time: 5:50 PM - To change this template use File | Settings | File Templates. ---%> -<%@ page contentType="text/html;charset=UTF-8" language="java" %> - - - - <% - String redirectURL = (String)request.getAttribute("redirect_url"); - %> - - - - - diff --git a/src/main/resources/webapp/jsp/mutation/mutation-file-example.txt b/src/main/resources/webapp/jsp/mutation/mutation-file-example.txt deleted file mode 100644 index c1aa00f3e5a..00000000000 --- a/src/main/resources/webapp/jsp/mutation/mutation-file-example.txt +++ /dev/null @@ -1,39 +0,0 @@ -Hugo_Symbol Sample_ID Protein_Change Mutation_Type Chromosome Start_Position End_Position Reference_Allele Variant_Allele -AR TCGA-13-0760 L729I Missense_Mutation 23 66937331 66937331 T A -AR TCGA-BS-A0UF R832* Nonsense_Mutation 23 66942713 66942713 C T -AR TCGA-D1-A17M L185P Missense_Mutation 23 66765542 66765542 T C -AR TCGA-B5-A0JY K222N Missense_Mutation 23 66765654 66765654 G T -BRCA1 TCGA-24-2298 Q1395fs Frame_Shift_Ins 17 41242962 41242963 - GA -BRCA1 TCGA-09-1669 E1345fs Frame_Shift_Del 17 41243513 41243513 T - -BRCA1 TCGA-25-1625 E116* Nonsense_Mutation 17 41256234 41256234 C A -BRCA1 TCGA-13-0804 C47W Missense_Mutation 17 41258544 41258544 G C -BRCA1 TCGA-23-1027 E23fs Frame_Shift_Del 17 41276045 41276046 CT - -BRCA1 TCGA-23-1118 E23fs Frame_Shift_Del 17 41276045 41276046 CT - -BRCA1 TCGA-AP-A051 L49M Missense_Mutation 17 41258540 41258540 G T -BRCA1 TCGA-B5-A11E A942V Missense_Mutation 17 41244723 41244723 G A -BRCA1 TCGA-BS-A0UF D1778_splice Splice_Site 17 41201212 41201212 C A -BRCA2 TCGA-13-0793 T3085fs Frame_Shift_Del 13 32954281 32954282 AG - -BRCA2 TCGA-24-1103 K1638E Missense_Mutation 13 32913404 32913404 A G -BRCA2 TCGA-24-2024 Y1710fs Frame_Shift_Del 13 32913620 32913623 TATG - -BRCA2 TCGA-04-1367 E294* Nonsense_Mutation 13 32906495 32906495 G T -BRCA2 TCGA-23-1030 T1354M Missense_Mutation 13 32912553 32912553 C T -BRCA2 TCGA-13-0792 E1143D Missense_Mutation 13 32911921 32911921 A T -BRCA2 TCGA-24-1555 E2878_splice Splice_Site 13 32950806 32950806 G C -BRCA2 TCGA-B5-A11E R2842C Missense_Mutation 13 32945129 32945129 C T -BRCA2 TCGA-B5-A0JY R2842C Missense_Mutation 13 32945129 32945129 C T -BRCA2 TCGA-AP-A059 S3239Y Missense_Mutation 13 32972366 32972366 C A -BRCA2 TCGA-BS-A0UV E1441* Nonsense_Mutation 13 32912813 32912813 G T -BRCA2 TCGA-AX-A05Z E897* Nonsense_Mutation 13 32911181 32911181 G T -POLE TCGA-57-1582 N1869K Missense_Mutation 12 133214671 133214671 G C -POLE TCGA-24-1104 T2245N Missense_Mutation 12 133201504 133201504 G T -POLE TCGA-AX-A05Z S1930* Nonsense_Mutation 12 133212500 133212500 G T -POLE TCGA-AP-A059 L2112M Missense_Mutation 12 133202900 133202900 G T -POLE TCGA-AP-A059 A25T Missense_Mutation 12 133257855 133257855 C T -TP53 TCGA-FI-A2EX R248W Missense_Mutation 17 7577539 7577539 G A -TP53 TCGA-B5-A11N T256fs Frame_Shift_Ins 17 7577514 7577515 - T -TP53 TCGA-DI-A1NN Q144* Nonsense_Mutation 17 7578500 7578500 G A -TP53 TCGA-AX-A0IU P278fs Frame_Shift_Ins 17 7577105 7577106 - GA -TP53 TCGA-AP-A1DQ R175H Missense_Mutation 17 7578406 7578406 C T -TP53 TCGA-AJ-A23M 277_277C>CC In_Frame_Ins 17 7577107 7577108 - CAG -TP53 TCGA-EY-A212 V173L Missense_Mutation 17 7578413 7578413 C G -TP53 TCGA-D1-A16I I332_splice Splice_Site 17 7574034 7574034 C G diff --git a/src/main/resources/webapp/jsp/mutation/mutationMapperTemplates.html b/src/main/resources/webapp/jsp/mutation/mutationMapperTemplates.html deleted file mode 100644 index 726553c4c9d..00000000000 --- a/src/main/resources/webapp/jsp/mutation/mutationMapperTemplates.html +++ /dev/null @@ -1,731 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/webapp/jsp/mutation/standalone_mutation_view.jsp b/src/main/resources/webapp/jsp/mutation/standalone_mutation_view.jsp deleted file mode 100644 index c3f9a98f60a..00000000000 --- a/src/main/resources/webapp/jsp/mutation/standalone_mutation_view.jsp +++ /dev/null @@ -1,123 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.util.GlobalProperties" %> - - - - - - - - - - diff --git a/src/main/resources/webapp/jsp/mutation_details.jsp b/src/main/resources/webapp/jsp/mutation_details.jsp deleted file mode 100644 index c5b3140bcdc..00000000000 --- a/src/main/resources/webapp/jsp/mutation_details.jsp +++ /dev/null @@ -1,93 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> -
- loading -
- - - - diff --git a/src/main/resources/webapp/jsp/mutation_views.jsp b/src/main/resources/webapp/jsp/mutation_views.jsp deleted file mode 100644 index 4c40c313c7b..00000000000 --- a/src/main/resources/webapp/jsp/mutation_views.jsp +++ /dev/null @@ -1,33 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ include file="src/main/webapp/jsp/mutation/mutationMapperTemplates.html" %> diff --git a/src/main/resources/webapp/jsp/mutex_tab.jsp b/src/main/resources/webapp/jsp/mutex_tab.jsp deleted file mode 100644 index 9cefc71c6ea..00000000000 --- a/src/main/resources/webapp/jsp/mutex_tab.jsp +++ /dev/null @@ -1,74 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.stats.OddsRatio" %> -<%@ page import="org.mskcc.cbio.portal.model.GeneWithScore" %> -<%@ page import="java.text.DecimalFormat" %> -<%@ page import="java.util.HashMap" %> -<%@ page import="java.util.Set" %> -<%@ page import="java.util.HashSet" %> -<%@ page import="org.apache.commons.lang3.math.DoubleRange" %> -<%@ page import="java.io.PrintWriter" %> -<%@ page import="java.io.IOException" %> - -
-
-
- - \ No newline at end of file diff --git a/src/main/resources/webapp/jsp/network_div.jsp b/src/main/resources/webapp/jsp/network_div.jsp deleted file mode 100644 index 5f6f28abe42..00000000000 --- a/src/main/resources/webapp/jsp/network_div.jsp +++ /dev/null @@ -1,54 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -
-
- - - - - - -
-
- -
-
-
- loading -
-
-
- -
-
-
diff --git a/src/main/resources/webapp/jsp/network_help.jsp b/src/main/resources/webapp/jsp/network_help.jsp deleted file mode 100644 index 44df79bd004..00000000000 --- a/src/main/resources/webapp/jsp/network_help.jsp +++ /dev/null @@ -1,278 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -

- About the Network View -

-

- The network view shows the genes you entered (referred to as seed nodes) in the context of biological interactions derived from public pathway databases. - Each gene in the network view is color-coded with multi-dimensional genomic data derived from the cancer study you have selected. -

- -

- Source of Pathway Data -

-

- Pathway and interaction data is from HPRD, - Reactome, - NCI-Nature Pathway Interaction Database, - and the MSKCC Cancer Call Map, - as derived from Pathway Commons. -

- -

- Source of Drug Data -

-

- Drug data is derived from PiHelper. -

- -

- Seed Nodes vs. Linker Nodes -

-

- A seed node represents a gene that you have entered. - A linker node represents a gene that connects to one or more of your seed genes. -

-

- Seed nodes are represented with a thick border:

- seed node -

-

- Linker nodes are represented with a thin border:

- linker node -

- -

- Visualization Summary of Genomic Data -

-

- The exact genomic data displayed on the network depends on the genomic profiles you have selected. - For example, you can chose to include mutation, copy number and mRNA expression profiles. -

-

- By default, each node is color coded along a white to red color gradient, - indicating the total frequency of alteration across the selected case set - (deeper red indicates higher frequency of alteration). -

-

- For example, EGFR is frequently altered in glibolastoma:

- altered node -

-

- By contrast, STAT3 is not altered at all in glioblastoma:

- not altered node -

- -

- If you mouse over a node, or select "View::Always Show Profile Data", - you will see additional details regarding the genomic alterations affecting the gene. - This breaks down into mutation, copy number and mRNA expression changes affecting the gene across all cases. -

-

- Click here to see the gene legend. -

- -

- Drug Information -

-

- Drugs targeting genes in the network are hidden by default. If you would like - to see them, select "Show All Drugs" or, "Show FDA Approved Drugs" or "Show Cancer Drugs" - from the drop-down box under the "Genes & Drugs" tab. -

-

- Number of Genes Targeted shown in the drug inspector refers to the total number of genes - (regardless of whether or not any such gene is in the current network of interest) targeted by this drug. -

-

- Click here to see the drug legend. -

- -

- Understanding Interaction and Edge Types -

-

- The interaction types are derived from the BioPAX to binary interaction mapping rules defined within Pathway Commons. - They are encoded by different edge colors and can be seleted on the "Interactions" tab to the right of the network. - In addition, if selected, drug-gene interactions are shown as edges in the network. The interaction types are: -

    -
  • - Controls-state-change-of: - First protein controls a reaction that changes the state of the second protein. -
  • -
  • - Controls-transport-of: - First protein controls a reaction that changes the cellular location of the second protein. -
  • -
  • - Controls-phosphorylation-of: - First protein controls a reaction that changes the phosphorylation status of the second protein. -
  • -
  • - Controls-expression-of: - First protein controls a conversion or a template reaction that changes expression of the second protein. -
  • -
  • - Catalysis-precedes: - First protein controls a reaction whose output molecule is input to another reaction controled by the second protein. -
  • -
  • - In-complex-with: - Proteins are members of the same complex. -
  • -
  • - Interacts-with: - Proteins are participants of the same MolecularInteraction. -
  • -
  • - Neighbor-of: - Proteins are participants or controlers of the same interaction. -
  • -
  • - Consumption-controled-by: - The small molecule is consumed by a reaction that is controled by a protein -
  • -
  • - Controls-production-of: - The protein controls a reaction of which the small molecule is an output. -
  • -
  • - Controls-transport-of-chemical: - The protein controls a reaction that changes cellular location of the small molecule. -
  • -
  • - Chemical-affects: - A small molecule has an effect on the protein state. -
  • -
  • - Reacts-with: - Small molecules are input to a biochemical reaction. -
  • -
  • - Used-to-produce: - A reaction consumes a small molecule to produce another small molecule. -
  • -
-

-

- Click here to see the color codes. -

-

- Complete details are available on the Pathway Commons web site. -

-

- By default, redundant interactions are merged are merged into a single edge. - To see all interactions, uncheck "Merge Interactions" in the "View" menu. -

- -

- Complexity Management -

-

- There are a number of options to better deal with complex networks: -

    -
  • - Hide Selected/Crop: - Selected nodes can be hidden using "Topology::Hide Selected". - Alternatively, you can select the set of nodes that you would like to view and hide the rest - of the network using "Topology::Show Only Selected". - Alternatively, buttons are available for these operations on the "Genes & Drugs" tab. -
  • -
  • - Filter by Interaction Type or Source: - If you are interested in only certain types of interactions or interactions from selected sources, - you may use the filtering mechanisms on the "Interactions" tab by checking the corresponding check boxes and clicking "Update". -
  • -
  • - Filter by Total Alteration: - Networks can be filtered based on alteration frequencies of individual nodes using a slider under the "Genes & Drugs" tab. - You can specify a threshold of total alteration frequency - nodes with alteration frequencies below the threshold will be filtered out, - but seed nodes are always kept in the network. -
  • -
  • - Filter Drugs by FDA Approval: - Networks can be filtered based on whether drugs associated with genes of this network are FDA approved or not. -
  • -
  • - Filter Cancer Drugs: - Networks can be filtered based on whether drugs associated with genes of this network are cancer drugs or not. - Notice that all cancer drugs are FDA approved. -
  • -
-

-

- All filtering can be undone by clicking "Unhide" in the "Topology" menu. -

-

- When the flag "Remove Disconnected Nodes on Hide" in the "Topology" menu is checked, - an automatic layout is performed upon all changes to the network topology. -

- -

- Performing Layout -

-

- A Force-Directed layout algorithm is used by default. - However, you may choose to re-perform the layout with different parameters (by selecting "Layout::Layout Properties ...") or - after the topology of the network changes with operations such as hiding or filtering. - If you would like the layout to be performed automatically upon such operations - simply check "Layout::Auto Layout on Changes". -

- -

- Exporting Networks -

-

- You can export a network to a PNG file. - To do so, select "File::Save as Image (PNG)". - We do not currently support export to PDF. -

- -

- Detailed Process Level (SBGN) View -

-

- When you are interested in process level details of an interaction, - you may either right-click on that interaction or click the "Detailed Process (SBGN)" button - in the Details tab while inspecting the interaction. - This will pop up a detailed process view in SBGN Process Description Language. - The shown network corresponds to all paths between source and target genes of that interaction as returned by Pathway Commons' web service. - SBGN view allows users to modify the process level view in many ways, including changing its layout and topology through complexity management techniques such as hiding or collapsing. - You may also store the current network as a static image or in SBGN-ML format. For further help, please refer to the Help menu of this view. -

-

- Technology -

-

- Network visualization is powered by Cytoscape.js and SBGNViz.js. -

diff --git a/src/main/resources/webapp/jsp/network_menu.jsp b/src/main/resources/webapp/jsp/network_menu.jsp deleted file mode 100644 index b4b48850d16..00000000000 --- a/src/main/resources/webapp/jsp/network_menu.jsp +++ /dev/null @@ -1,158 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<% -Boolean includeNetLegend = (Boolean)request.getAttribute("include_network_legend"); -if (includeNetLegend==null) { - includeNetLegend = Boolean.TRUE; -} -%> - - -
- -
diff --git a/src/main/resources/webapp/jsp/network_tabs.jsp b/src/main/resources/webapp/jsp/network_tabs.jsp deleted file mode 100644 index 38af7adf8d2..00000000000 --- a/src/main/resources/webapp/jsp/network_tabs.jsp +++ /dev/null @@ -1,217 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<% -Boolean includeHelpTab = (Boolean)request.getAttribute("include_network_help_tab"); -if (includeHelpTab==null) { - includeHelpTab = Boolean.TRUE; -} -%> - -
- -
-
-

-
- -
-

-
- -
- - - - - -
-
- -
- - - - - -
-
-
-
- - - - - - - - -
- - - - - - - - - -
- - - - - -
- - - -
-
-
-
-
-
-
-
- -
- -
-
- -
-
-
- Currently there is no selected node/edge. Please, select a node/edge to see details.
-
-
-
-
-
- <%if(includeHelpTab){%> -
- -
- <%}%> -
- -<% /* -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- Edge Types: -
-
In Same Component
-
-
-
-
Reacts With
-
-
-
-
State Change
-
-
-
-
Other
-
-
-
-
Merged (with different types)
-
-
-
-
-
-*/ %> diff --git a/src/main/resources/webapp/jsp/network_views.jsp b/src/main/resources/webapp/jsp/network_views.jsp deleted file mode 100644 index bcff6499ab6..00000000000 --- a/src/main/resources/webapp/jsp/network_views.jsp +++ /dev/null @@ -1,780 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - - - - - - - - - diff --git a/src/main/resources/webapp/jsp/networks.jsp b/src/main/resources/webapp/jsp/networks.jsp deleted file mode 100644 index 81a1cc11a79..00000000000 --- a/src/main/resources/webapp/jsp/networks.jsp +++ /dev/null @@ -1,67 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - - - - - - \ No newline at end of file diff --git a/src/main/resources/webapp/jsp/oncokb/oncokb-card-template.html b/src/main/resources/webapp/jsp/oncokb/oncokb-card-template.html deleted file mode 100644 index f1b484a23d4..00000000000 --- a/src/main/resources/webapp/jsp/oncokb/oncokb-card-template.html +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - diff --git a/src/main/resources/webapp/jsp/oncoprint/cna-file-example.txt b/src/main/resources/webapp/jsp/oncoprint/cna-file-example.txt deleted file mode 100644 index 82b00b59822..00000000000 --- a/src/main/resources/webapp/jsp/oncoprint/cna-file-example.txt +++ /dev/null @@ -1,3 +0,0 @@ -Hugo_Symbol Entrez_Gene_Id TCGA-04-1348 TCGA-04-1357 TCGA-04-1362 TCGA-04-1364 TCGA-04-1365 TCGA-04-1514 TCGA-09-0366 TCGA-09-0369 TCGA-09-1662 TCGA-09-1666 TCGA-09-1669 TCGA-09-2044 TCGA-09-2045 TCGA-09-2051 TCGA-09-2056 TCGA-10-0928 TCGA-13-0730 TCGA-13-0800 TCGA-13-0890 TCGA-13-0893 TCGA-13-0897 TCGA-13-0899 TCGA-13-0913 TCGA-13-0916 TCGA-13-0920 TCGA-13-0924 TCGA-13-1403 TCGA-13-1405 TCGA-13-1410 TCGA-13-1481 TCGA-13-1497 TCGA-13-1498 TCGA-13-1505 TCGA-13-1506 TCGA-13-1507 TCGA-13-1512 TCGA-13-2060 TCGA-23-1023 TCGA-23-1026 TCGA-23-1027 TCGA-23-1120 TCGA-23-1122 TCGA-23-1123 TCGA-23-2077 TCGA-23-2081 TCGA-24-0975 TCGA-24-1103 TCGA-24-1413 TCGA-24-1416 TCGA-24-1417 TCGA-24-1418 TCGA-24-1419 TCGA-24-1423 TCGA-24-1424 TCGA-24-1427 TCGA-24-1428 TCGA-24-1436 TCGA-24-1469 TCGA-24-1474 TCGA-24-1544 TCGA-24-1548 TCGA-24-1549 TCGA-24-1551 TCGA-24-1552 TCGA-24-1553 TCGA-24-1555 TCGA-24-1556 TCGA-24-1557 TCGA-24-1558 TCGA-24-1560 TCGA-24-1562 TCGA-24-1563 TCGA-24-1564 TCGA-24-1567 TCGA-24-1603 TCGA-24-1604 TCGA-24-1616 TCGA-24-2019 TCGA-24-2024 TCGA-24-2035 TCGA-24-2038 TCGA-24-2254 TCGA-24-2261 TCGA-24-2262 TCGA-24-2267 TCGA-24-2271 TCGA-24-2281 TCGA-24-2288 TCGA-24-2290 TCGA-24-2298 TCGA-25-1313 TCGA-25-1315 TCGA-25-1316 TCGA-25-1317 TCGA-25-1318 TCGA-25-1319 TCGA-25-1321 TCGA-25-1322 TCGA-25-1329 TCGA-25-1623 TCGA-25-1625 TCGA-25-1627 TCGA-25-1630 TCGA-25-1631 TCGA-25-1632 TCGA-25-1633 TCGA-25-1634 TCGA-25-1635 TCGA-25-2391 TCGA-25-2392 TCGA-25-2393 TCGA-25-2396 TCGA-25-2399 TCGA-25-2400 TCGA-25-2404 TCGA-25-2409 TCGA-29-2427 TCGA-30-1862 TCGA-30-1891 TCGA-31-1953 TCGA-36-1568 TCGA-36-1570 TCGA-36-1571 TCGA-36-1574 TCGA-36-1575 TCGA-36-1577 TCGA-36-1578 TCGA-36-1580 TCGA-57-1582 TCGA-57-1583 TCGA-57-1584 TCGA-57-1993 TCGA-59-2348 TCGA-59-2350 TCGA-59-2351 TCGA-59-2352 TCGA-59-2355 TCGA-59-2363 TCGA-61-1728 TCGA-61-1736 TCGA-61-1919 TCGA-61-1995 TCGA-61-1998 TCGA-61-2000 TCGA-61-2008 TCGA-61-2009 TCGA-61-2012 TCGA-61-2016 TCGA-61-2088 TCGA-61-2092 TCGA-61-2094 TCGA-61-2097 TCGA-61-2102 TCGA-61-2104 TCGA-61-2109 TCGA-61-2110 TCGA-61-2111 TCGA-61-2113 -BRCA1 672 -1 0 0 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 -1 0 -1 -1 1 1 -1 -1 0 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 -1 0 1 2 -1 -1 -1 0 0 -1 -1 0 -1 -1 -1 -1 -1 -1 0 -1 0 -1 -1 -1 -1 -1 -1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 0 -1 0 -1 -1 1 -1 0 -1 -1 -1 -1 -1 1 -1 -1 0 0 -1 -1 -1 -1 -1 -1 0 -1 -1 1 -1 0 -1 -1 1 -1 -1 0 -1 -1 -1 -1 -1 1 -1 -1 -1 -1 0 -1 -1 0 -1 -1 -1 -1 -1 0 -1 -1 -1 -1 -1 0 -1 0 -1 -1 -1 0 -1 -1 0 -1 -1 -1 -1 -1 -BRCA2 675 -1 0 0 2 -1 -1 -1 1 0 0 0 0 -1 0 -1 -1 -1 -1 0 -1 0 -1 2 0 -1 -1 0 0 -1 2 0 -1 1 0 0 -1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 1 -1 0 -1 0 -1 1 -1 -1 -1 -1 -1 -1 -1 0 -1 0 0 -1 -1 0 -1 -1 0 -1 -1 -1 -1 -1 0 0 -1 -1 -1 -1 0 0 -1 -1 0 -1 -1 0 1 -1 -1 -1 2 -1 0 0 1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 -1 0 0 -1 -1 -1 1 -1 0 1 0 -1 1 0 -1 -1 -1 1 0 0 1 -1 -1 0 0 2 1 -1 -1 -1 0 -1 -1 -1 -1 0 -1 -1 -1 0 diff --git a/src/main/resources/webapp/jsp/oncoprint/controls-templates.jsp b/src/main/resources/webapp/jsp/oncoprint/controls-templates.jsp deleted file mode 100644 index 2246cba8c68..00000000000 --- a/src/main/resources/webapp/jsp/oncoprint/controls-templates.jsp +++ /dev/null @@ -1,80 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - - - - - - \ No newline at end of file diff --git a/src/main/resources/webapp/jsp/oncoprint/example-clinic-events.txt b/src/main/resources/webapp/jsp/oncoprint/example-clinic-events.txt deleted file mode 100644 index 4ae9348a133..00000000000 --- a/src/main/resources/webapp/jsp/oncoprint/example-clinic-events.txt +++ /dev/null @@ -1,99 +0,0 @@ -SAMPLE_ID TUMOR_STAGE_2009 GRADE\n\ -sample string string\n\ -TCGA-61-1895 IIIB G3\n\ -TCGA-13-1510 IIIC G3\n\ -TCGA-23-1809 IIC G3\n\ -TCGA-20-1687 IV G3\n\ -TCGA-13-1404 IIIC G3\n\ -TCGA-13-1506 IIIC G3\n\ -TCGA-23-1116 IIIC G3\n\ -TCGA-20-1686 IIIC G3\n\ -TCGA-13-1505 IIIC G3\n\ -TCGA-24-1846 IIIC G3\n\ -TCGA-13-1412 IV G3\n\ -TCGA-23-1111 IIIC G3\n\ -TCGA-24-1843 IIIC G3\n\ -TCGA-24-1844 IIIC G3\n\ -TCGA-23-1120 IIIC G3\n\ -TCGA-13-1507 IIIC G3\n\ -TCGA-24-1845 IIIC G3\n\ -TCGA-24-1842 IIIC G3\n\ -TCGA-24-1847 IV G3\n\ -TCGA-13-1512 IIIC G3\n\ -TCGA-61-2088 IIIC G3\n\ -TCGA-13-1407 IIIC G3\n\ -TCGA-23-1121 IIIC G3\n\ -TCGA-13-1509 IV G3\n\ -TCGA-29-1781 IIIC G3\n\ -TCGA-13-0921 IIIC G3\n\ -TCGA-13-1410 IV NA\n\ -TCGA-24-1426 IIIC G3\n\ -TCGA-24-1416 IV G3\n\ -TCGA-24-1470 IIIB G3\n\ -TCGA-29-1784 IIIC G3\n\ -TCGA-24-1850 IIIC G3\n\ -TCGA-09-2044 IIB G3\n\ -TCGA-24-1425 IIIC G3\n\ -TCGA-24-1849 IIIC G3\n\ -TCGA-24-1423 IIIC G3\n\ -TCGA-13-0924 IV G3\n\ -TCGA-13-0923 IIIC G3\n\ -TCGA-24-1413 IIIC G3\n\ -TCGA-13-0802 IIIC G3\n\ -TCGA-29-1783 IIIC G3\n\ -TCGA-24-1424 IIIC G3\n\ -TCGA-13-1405 IV G3\n\ -TCGA-24-1417 IV G3\n\ -TCGA-24-1418 IIIC G3\n\ -TCGA-13-0799 IIIC G3\n\ -TCGA-13-1496 IIIC G3\n\ -TCGA-61-1899 IIIC G3\n\ -TCGA-61-1900 IIIB G3\n\ -TCGA-13-0801 IIIC G3\n\ -TCGA-13-0800 IIIC G3\n\ -TCGA-13-0768 IIIC G3\n\ -TCGA-61-1904 IIIC G3\n\ -TCGA-24-1419 IIIC G3\n\ -TCGA-13-2060 IV G3\n\ -TCGA-13-0797 IIIC G3\n\ -TCGA-24-1469 IIIC G3\n\ -TCGA-24-1920 IIIC G3\n\ -TCGA-23-1024 IV G3\n\ -TCGA-23-1029 IIIC G3\n\ -TCGA-13-1403 IIIC G3\n\ -TCGA-13-1504 IIIC G3\n\ -TCGA-09-2056 IIIC G3\n\ -TCGA-13-0919 IIIC G3\n\ -TCGA-29-1778 IIIC G3\n\ -TCGA-20-1685 IIIC G3\n\ -TCGA-20-1684 IIIC G3\n\ -TCGA-13-0916 IIIC G3\n\ -TCGA-29-1769 IIIC G3\n\ -TCGA-20-1682 IIIC NA\n\ -TCGA-13-0910 IIIC G3\n\ -TCGA-13-0762 IIIC G3\n\ -TCGA-29-1711 IIIC G2\n\ -TCGA-61-1910 IIC G3\n\ -TCGA-09-2053 IIIC G3\n\ -TCGA-61-1737 IV G3\n\ -TCGA-13-0906 IIIC G3\n\ -TCGA-29-2428 IIIC G3\n\ -TCGA-13-0905 IIIC G3\n\ -TCGA-25-2391 IIIC G3\n\ -TCGA-61-1913 IIIB G3\n\ -TCGA-61-2092 IIIC G3\n\ -TCGA-13-0900 IIIC G3\n\ -TCGA-61-2097 IIC G2\n\ -TCGA-13-0889 IV NA\n\ -TCGA-04-1347 IV G3\n\ -TCGA-13-0890 IIIC G3\n\ -TCGA-61-2098 IIIC G2\n\ -TCGA-13-0888 IIIC G3\n\ -TCGA-61-1915 IIC G3\n\ -TCGA-04-1367 IIIC G3\n\ -TCGA-13-1492 IIIC G3\n\ -TCGA-13-0886 IIIC G3\n\ -TCGA-61-2094 IIIC G3\n\ -TCGA-09-2050 IIA G2\n\ -TCGA-13-1481 IIIC G2\n\ -TCGA-23-1118 IIIC G3\n\ diff --git a/src/main/resources/webapp/jsp/oncoprint/example-genomic-events.txt b/src/main/resources/webapp/jsp/oncoprint/example-genomic-events.txt deleted file mode 100644 index 1c84dcae266..00000000000 --- a/src/main/resources/webapp/jsp/oncoprint/example-genomic-events.txt +++ /dev/null @@ -1,591 +0,0 @@ -Sample Gene Alteration Type\n\ -TCGA-25-2392-01 TP53 FUSION FUSION\n\ -TCGA-25-2393-01 TP53 FUSION FUSION\n\ -TCGA-04-1331-01 PTEN HOMDEL CNA\n\ -TCGA-04-1365-01 PTEN HOMDEL CNA\n\ -TCGA-04-1648-01 TP53 HOMDEL CNA\n\ -TCGA-09-1666-01 PTEN AMP CNA\n\ -TCGA-13-0720-01 PTEN HOMDEL CNA\n\ -TCGA-13-0801-01 BRCA1 HOMDEL CNA\n\ -TCGA-13-0801-01 PTEN HOMDEL CNA\n\ -TCGA-13-0905-01 PTEN HOMDEL CNA\n\ -TCGA-13-0924-01 PTEN HOMDEL CNA\n\ -TCGA-13-1405-01 PTEN HOMDEL CNA\n\ -TCGA-13-1408-01 TP53 HOMDEL CNA\n\ -TCGA-13-1488-01 PTEN HOMDEL CNA\n\ -TCGA-23-1023-01 PTEN HOMDEL CNA\n\ -TCGA-23-1032-01 PTEN HOMDEL CNA\n\ -TCGA-23-1107-01 PTEN HOMDEL CNA\n\ -TCGA-23-1114-01 BRCA2 HOMDEL CNA\n\ -TCGA-23-1118-01 PTEN AMP CNA\n\ -TCGA-23-1121-01 PTEN AMP CNA\n\ -TCGA-23-2084-01 TP53 HOMDEL CNA\n\ -TCGA-24-0968-01 PTEN HOMDEL CNA\n\ -TCGA-24-0970-01 BRCA2 AMP CNA\n\ -TCGA-24-1103-01 PTEN HOMDEL CNA\n\ -TCGA-24-1474-01 TP53 AMP CNA\n\ -TCGA-24-1567-01 PTEN HOMDEL CNA\n\ -TCGA-24-2030-01 PTEN HOMDEL CNA\n\ -TCGA-24-2036-01 PTEN HOMDEL CNA\n\ -TCGA-24-2262-01 PTEN HOMDEL CNA\n\ -TCGA-24-2297-01 PTEN HOMDEL CNA\n\ -TCGA-25-1322-01 BRCA2 AMP CNA\n\ -TCGA-25-2391-01 PTEN HOMDEL CNA\n\ -TCGA-25-2401-01 BRCA2 HOMDEL CNA\n\ -TCGA-29-1697-01 PTEN AMP CNA\n\ -TCGA-29-1702-01 TP53 AMP CNA\n\ -TCGA-29-1761-01 PTEN HOMDEL CNA\n\ -TCGA-30-1860-01 PTEN HOMDEL CNA\n\ -TCGA-31-1951-01 PTEN HOMDEL CNA\n\ -TCGA-31-1959-01 BRCA1 HOMDEL CNA\n\ -TCGA-31-1959-01 PTEN HOMDEL CNA\n\ -TCGA-36-1570-01 PTEN HOMDEL CNA\n\ -TCGA-57-1586-01 BRCA1 HOMDEL CNA\n\ -TCGA-61-1728-01 PTEN HOMDEL CNA\n\ -TCGA-61-1895-01 PTEN HOMDEL CNA\n\ -TCGA-61-1907-01 BRCA2 HOMDEL CNA\n\ -TCGA-61-2012-01 TP53 AMP CNA\n\ -TCGA-61-2094-01 PTEN HOMDEL CNA\n\ -TCGA-61-2097-01 BRCA2 HOMDEL CNA\n\ -TCGA-29-1702-01 TP53 UP EXP\n\ -TCGA-61-2012-01 TP53 UP EXP\n\ -TCGA-36-1570-01 PTEN DOWN EXP\n\ -TCGA-57-1586-01 BRCA1 DOWN EXP\n\ -TCGA-61-1728-01 PTEN DOWN EXP\n\ -TCGA-61-1895-01 PTEN DOWN EXP\n\ -TCGA-61-1907-01 BRCA2 DOWN EXP\n\ -TCGA-25-1625-01 BRCA1 E116* TRUNC\n\ -TCGA-04-1357-01 BRCA1 Q1538A MISSENSE\n\ -TCGA-13-0893-01 BRCA1 K503fs TRUNC\n\ -TCGA-61-2109-01 BRCA1 K654fs TRUNC\n\ -TCGA-13-0761-01 BRCA1 R1495_splice TRUNC\n\ -TCGA-23-1118-01 BRCA1 E23fs TRUNC\n\ -TCGA-29-2427-01 BRCA1 L431* TRUNC\n\ -TCGA-23-1122-01 BRCA1 Q1756fs TRUNC\n\ -TCGA-25-2392-01 BRCA1 E1345fs TRUNC\n\ -TCGA-23-1027-01 BRCA1 E23fs TRUNC\n\ -TCGA-25-1632-01 BRCA1 L1216fs TRUNC\n\ -TCGA-23-1026-01 BRCA1 G813fs TRUNC\n\ -TCGA-13-0804-01 BRCA1 C47W MISSENSE\n\ -TCGA-24-2298-01 BRCA1 Q1395fs TRUNC\n\ -TCGA-61-2008-01 BRCA1 W1815* TRUNC\n\ -TCGA-09-2045-01 BRCA1 Q1779fs TRUNC\n\ -TCGA-04-1356-01 BRCA1 V722fs TRUNC\n\ -TCGA-25-1630-01 BRCA1 K519fs TRUNC\n\ -TCGA-24-1470-01 BRCA1 L1676fs TRUNC\n\ -TCGA-13-0730-01 BRCA1 R1835* TRUNC\n\ -TCGA-13-0883-01 BRCA1 Q1756fs TRUNC\n\ -TCGA-25-2401-01 BRCA1 Q1756fs TRUNC\n\ -TCGA-13-0903-01 BRCA1 R504fs TRUNC\n\ -TCGA-13-0887-01 BRCA1 E23fs TRUNC\n\ -TCGA-13-1494-01 BRCA1 K45_splice TRUNC\n\ -TCGA-09-2051-01 BRCA1 Q1756fs TRUNC\n\ -TCGA-23-2078-01 BRCA1 E23fs TRUNC\n\ -TCGA-23-2079-01 BRCA1 E23fs TRUNC\n\ -TCGA-10-0931-01 BRCA1 E23fs TRUNC\n\ -TCGA-59-2348-01 BRCA1 E797* TRUNC\n\ -TCGA-23-2077-01 BRCA1 Q1756fs TRUNC\n\ -TCGA-09-1669-01 BRCA1 E1345fs TRUNC\n\ -TCGA-23-2081-01 BRCA1 Q1756fs TRUNC\n\ -TCGA-13-1408-01 BRCA1 E23fs TRUNC\n\ -TCGA-13-1489-01 BRCA1 N1265fs TRUNC\n\ -TCGA-25-1318-01 BRCA2 L1491fs TRUNC\n\ -TCGA-13-0793-01 BRCA2 T3085fs TRUNC\n\ -TCGA-24-1463-01 BRCA2 G602fs TRUNC\n\ -TCGA-13-0913-01 BRCA2 E1857fs TRUNC\n\ -TCGA-04-1367-01 BRCA2 E294* TRUNC\n\ -TCGA-24-1562-01 BRCA2 K3326* TRUNC\n\ -TCGA-04-1331-01 BRCA2 C711* TRUNC\n\ -TCGA-24-1103-01 BRCA2 K1638E MISSENSE\n\ -TCGA-13-0885-01 BRCA2 K1406fs TRUNC\n\ -TCGA-13-0890-01 BRCA2 V1229fs TRUNC\n\ -TCGA-13-1512-01 BRCA2 K3326* TRUNC\n\ -TCGA-23-1030-01 BRCA2 T1354M MISSENSE\n\ -TCGA-23-1026-01 BRCA2 K3326* TRUNC\n\ -TCGA-25-1634-01 BRCA2 E2878_splice TRUNC\n\ -TCGA-24-1555-01 BRCA2 T2607fs TRUNC\n\ -TCGA-13-0886-01 BRCA2 S1982fs TRUNC\n\ -TCGA-13-0792-01 BRCA2 E1143D MISSENSE\n\ -TCGA-24-2293-01 BRCA2 R2520* TRUNC\n\ -TCGA-23-1120-01 BRCA2 L3277fs TRUNC\n\ -TCGA-57-1584-01 BRCA2 Q1782fs TRUNC\n\ -TCGA-13-0900-01 BRCA2 T256fs TRUNC\n\ -TCGA-24-2280-01 BRCA2 S1982fs TRUNC\n\ -TCGA-24-0975-01 BRCA2 V211_splice TRUNC\n\ -TCGA-24-2288-01 BRCA2 T219fs TRUNC\n\ -TCGA-24-1417-01 BRCA2 R1704fs TRUNC\n\ -TCGA-13-1498-01 BRCA2 S1982fs TRUNC\n\ -TCGA-13-1499-01 BRCA2 S1982fs TRUNC\n\ -TCGA-13-0726-01 BRCA2 R2394* TRUNC\n\ -TCGA-25-2404-01 BRCA2 E342fs TRUNC\n\ -TCGA-13-1481-01 BRCA2 L2696fs TRUNC\n\ -TCGA-10-0930-01 PTEN V175L MISSENSE\n\ -TCGA-13-1492-01 PTEN R233fs TRUNC\n\ -TCGA-24-0968-01 TP53 H193R MISSENSE\n\ -TCGA-13-1505-01 TP53 P75fs TRUNC\n\ -TCGA-04-1336-01 TP53 R248W MISSENSE\n\ -TCGA-24-2261-01 TP53 Y163C MISSENSE\n\ -TCGA-13-0912-01 TP53 S261_splice TRUNC\n\ -TCGA-36-1580-01 TP53 R273C MISSENSE\n\ -TCGA-59-2352-01 TP53 G266V MISSENSE\n\ -TCGA-25-2409-01 TP53 R248W MISSENSE\n\ -TCGA-61-1919-01 TP53 I195T MISSENSE\n\ -TCGA-13-0919-01 TP53 V157F MISSENSE\n\ -TCGA-09-2051-01 TP53 P222fs TRUNC\n\ -TCGA-09-2050-01 TP53 L257Q MISSENSE\n\ -TCGA-25-1626-01 TP53 G245V MISSENSE\n\ -TCGA-09-2049-01 TP53 G245S MISSENSE\n\ -TCGA-24-1417-01 TP53 R248W MISSENSE\n\ -TCGA-24-1422-01 TP53 R248W MISSENSE\n\ -TCGA-13-0924-01 TP53 F270L MISSENSE\n\ -TCGA-61-2109-01 TP53 R306fs TRUNC\n\ -TCGA-24-1416-01 TP53 R282W MISSENSE\n\ -TCGA-24-1564-01 TP53 G187_splice TRUNC\n\ -TCGA-61-2088-01 TP53 MCN237del INFRAME\n\ -TCGA-10-0934-01 TP53 R248Q MISSENSE\n\ -TCGA-61-2003-01 TP53 R175H MISSENSE\n\ -TCGA-10-0934-01 TP53 R273H MISSENSE\n\ -TCGA-09-1666-01 TP53 Y126_splice TRUNC\n\ -TCGA-13-0714-01 TP53 S127F MISSENSE\n\ -TCGA-13-1510-01 TP53 R213* TRUNC\n\ -TCGA-36-1576-01 TP53 R337fs TRUNC\n\ -TCGA-25-1329-01 TP53 P47fs TRUNC\n\ -TCGA-13-1481-01 TP53 P177R MISSENSE\n\ -TCGA-04-1337-01 TP53 C135R MISSENSE\n\ -TCGA-24-1428-01 TP53 I195N MISSENSE\n\ -TCGA-24-1567-01 TP53 R282W MISSENSE\n\ -TCGA-04-1332-01 TP53 R181P MISSENSE\n\ -TCGA-04-1349-01 TP53 S241F MISSENSE\n\ -TCGA-61-2008-01 TP53 G117fs TRUNC\n\ -TCGA-13-0791-01 TP53 R273L MISSENSE\n\ -TCGA-09-1669-01 TP53 Q331_splice TRUNC\n\ -TCGA-24-2019-01 TP53 I232N MISSENSE\n\ -TCGA-24-1425-01 TP53 Y234C MISSENSE\n\ -TCGA-24-1423-01 TP53 P191del INFRAME\n\ -TCGA-10-0926-01 TP53 Y163C MISSENSE\n\ -TCGA-13-0760-01 TP53 L265P MISSENSE\n\ -TCGA-24-1556-01 TP53 A307_splice TRUNC\n\ -TCGA-24-1558-01 TP53 R273H MISSENSE\n\ -TCGA-25-2404-01 TP53 H214R MISSENSE\n\ -TCGA-24-1616-01 TP53 Y236C MISSENSE\n\ -TCGA-13-0720-01 TP53 A159V MISSENSE\n\ -TCGA-24-2280-01 TP53 Q192* TRUNC\n\ -TCGA-13-0793-01 TP53 C124fs TRUNC\n\ -TCGA-24-1604-01 TP53 A307_splice TRUNC\n\ -TCGA-09-1659-01 TP53 E294* TRUNC\n\ -TCGA-24-1413-01 TP53 E198* TRUNC\n\ -TCGA-09-1662-01 TP53 C176Y MISSENSE\n\ -TCGA-13-0724-01 TP53 V157F MISSENSE\n\ -TCGA-24-2030-01 TP53 G187_splice TRUNC\n\ -TCGA-13-1484-01 TP53 Y234N MISSENSE\n\ -TCGA-24-2254-01 TP53 S241F MISSENSE\n\ -TCGA-61-2101-01 TP53 P85fs TRUNC\n\ -TCGA-09-0366-01 TP53 K132N MISSENSE\n\ -TCGA-04-1365-01 TP53 Y126_splice TRUNC\n\ -TCGA-09-2053-01 TP53 Y163H MISSENSE\n\ -TCGA-24-2024-01 TP53 V272M MISSENSE\n\ -TCGA-23-1120-01 TP53 R110L MISSENSE\n\ -TCGA-24-0970-01 TP53 G187_splice TRUNC\n\ -TCGA-13-1489-01 TP53 R342* TRUNC\n\ -TCGA-24-1103-01 TP53 A307_splice TRUNC\n\ -TCGA-57-1993-01 TP53 R248Q MISSENSE\n\ -TCGA-25-1322-01 TP53 Y205C MISSENSE\n\ -TCGA-13-0751-01 TP53 L348fs TRUNC\n\ -TCGA-04-1356-01 TP53 Y220C MISSENSE\n\ -TCGA-10-0928-01 TP53 G105S MISSENSE\n\ -TCGA-23-2077-01 TP53 R175H MISSENSE\n\ -TCGA-13-0890-01 TP53 Y126_splice TRUNC\n\ -TCGA-04-1525-01 TP53 R282fs TRUNC\n\ -TCGA-23-1022-01 TP53 K164E MISSENSE\n\ -TCGA-13-0905-01 TP53 R273P MISSENSE\n\ -TCGA-30-1862-01 TP53 E224_splice TRUNC\n\ -TCGA-13-0765-01 TP53 AMP64_264L>LSSGNL INFRAME\n\ -TCGA-31-1953-01 TP53 V97fs TRUNC\n\ -TCGA-04-1514-01 TP53 Y126_splice TRUNC\n\ -TCGA-13-1509-01 TP53 L330fs TRUNC\n\ -TCGA-24-1419-01 TP53 R248Q MISSENSE\n\ -TCGA-25-1321-01 TP53 R273C MISSENSE\n\ -TCGA-20-0987-01 TP53 G105R MISSENSE\n\ -TCGA-23-1024-01 TP53 G108fs TRUNC\n\ -TCGA-24-2290-01 TP53 V274G MISSENSE\n\ -TCGA-23-1124-01 TP53 R156P MISSENSE\n\ -TCGA-61-2094-01 TP53 L130V MISSENSE\n\ -TCGA-25-1625-01 TP53 V216M MISSENSE\n\ -TCGA-61-1736-01 TP53 G245R MISSENSE\n\ -TCGA-13-0800-01 TP53 K132M MISSENSE\n\ -TCGA-24-1555-01 TP53 H179Q MISSENSE\n\ -TCGA-25-2391-01 TP53 E51fs TRUNC\n\ -TCGA-24-1434-01 TP53 L344fs TRUNC\n\ -TCGA-04-1517-01 TP53 R65* TRUNC\n\ -TCGA-09-1661-01 TP53 G187_splice TRUNC\n\ -TCGA-61-1995-01 TP53 C238Y MISSENSE\n\ -TCGA-31-1959-01 TP53 C238F MISSENSE\n\ -TCGA-24-1614-01 TP53 V157F MISSENSE\n\ -TCGA-36-1569-01 TP53 W53* TRUNC\n\ -TCGA-24-2271-01 TP53 K321* TRUNC\n\ -TCGA-23-1123-01 TP53 C176Y MISSENSE\n\ -TCGA-13-1507-01 TP53 T140fs TRUNC\n\ -TCGA-13-0913-01 TP53 P278R MISSENSE\n\ -TCGA-13-0899-01 TP53 Q317* TRUNC\n\ -TCGA-23-1110-01 TP53 C176Y MISSENSE\n\ -TCGA-25-1319-01 TP53 Y220C MISSENSE\n\ -TCGA-24-1548-01 TP53 Y220C MISSENSE\n\ -TCGA-13-0910-01 TP53 C275Y MISSENSE\n\ -TCGA-04-1346-01 TP53 H179R MISSENSE\n\ -TCGA-04-1350-01 TP53 H179R MISSENSE\n\ -TCGA-25-1326-01 TP53 E286K MISSENSE\n\ -TCGA-24-1549-01 TP53 V225_splice TRUNC\n\ -TCGA-13-0891-01 TP53 Y220C MISSENSE\n\ -TCGA-10-0931-01 TP53 Q136* TRUNC\n\ -TCGA-13-1411-01 TP53 C277F MISSENSE\n\ -TCGA-13-1498-01 TP53 I332_splice TRUNC\n\ -TCGA-24-2260-01 TP53 R248Q MISSENSE\n\ -TCGA-23-1030-01 TP53 R175H MISSENSE\n\ -TCGA-04-1342-01 TP53 N288fs TRUNC\n\ -TCGA-13-0723-01 TP53 T150fs TRUNC\n\ -TCGA-24-2289-01 TP53 R196* TRUNC\n\ -TCGA-61-1728-01 TP53 Y220C MISSENSE\n\ -TCGA-13-0883-01 TP53 C238fs TRUNC\n\ -TCGA-23-1026-01 TP53 K132R MISSENSE\n\ -TCGA-61-2097-01 TP53 R342* TRUNC\n\ -TCGA-59-2354-01 TP53 Y220C MISSENSE\n\ -TCGA-59-2350-01 TP53 Y220C MISSENSE\n\ -TCGA-59-2363-01 TP53 Y220C MISSENSE\n\ -TCGA-23-1122-01 TP53 R175H MISSENSE\n\ -TCGA-13-0887-01 TP53 R213* TRUNC\n\ -TCGA-13-0762-01 TP53 H193R MISSENSE\n\ -TCGA-59-2351-01 TP53 T140fs TRUNC\n\ -TCGA-25-2398-01 TP53 154_154G>GTDSTPPPG INFRAME\n\ -TCGA-25-1315-01 TP53 R273H MISSENSE\n\ -TCGA-24-2298-01 TP53 V225_splice TRUNC\n\ -TCGA-13-1497-01 TP53 R333fs TRUNC\n\ -TCGA-13-0792-01 TP53 C238fs TRUNC\n\ -TCGA-13-0903-01 TP53 Y205C MISSENSE\n\ -TCGA-30-1853-01 TP53 G245D MISSENSE\n\ -TCGA-57-1582-01 TP53 Y236C MISSENSE\n\ -TCGA-24-0966-01 TP53 G245V MISSENSE\n\ -TCGA-24-1557-01 TP53 Y126_splice TRUNC\n\ -TCGA-59-2355-01 TP53 Q331_splice TRUNC\n\ -TCGA-23-1023-01 TP53 D281G MISSENSE\n\ -TCGA-10-0927-01 TP53 P36fs TRUNC\n\ -TCGA-09-2044-01 TP53 G187_splice TRUNC\n\ -TCGA-13-0906-01 TP53 F134V MISSENSE\n\ -TCGA-25-1627-01 TP53 Y220C MISSENSE\n\ -TCGA-13-1482-01 TP53 R280I MISSENSE\n\ -TCGA-24-2281-01 TP53 R175H MISSENSE\n\ -TCGA-13-0889-01 TP53 R273C MISSENSE\n\ -TCGA-24-1562-01 TP53 S33_splice TRUNC\n\ -TCGA-13-1488-01 TP53 R306* TRUNC\n\ -TCGA-61-2016-01 TP53 E204* TRUNC\n\ -TCGA-04-1362-01 TP53 V225_splice TRUNC\n\ -TCGA-13-0717-01 TP53 AMP44_246GGM>V INFRAME\n\ -TCGA-61-2104-01 TP53 Y163N MISSENSE\n\ -TCGA-13-0885-01 TP53 W146* TRUNC\n\ -TCGA-24-2288-01 TP53 P250L MISSENSE\n\ -TCGA-13-0726-01 TP53 R282W MISSENSE\n\ -TCGA-10-0938-01 TP53 Q331_splice TRUNC\n\ -TCGA-24-2035-01 TP53 S315fs TRUNC\n\ -TCGA-13-1492-01 TP53 G187_splice TRUNC\n\ -TCGA-24-1105-01 TP53 V157F MISSENSE\n\ -TCGA-13-1494-01 TP53 G105C MISSENSE\n\ -TCGA-24-0979-01 TP53 R248Q MISSENSE\n\ -TCGA-04-1361-01 TP53 Y234C MISSENSE\n\ -TCGA-25-1628-01 TP53 E51* TRUNC\n\ -TCGA-13-1491-01 TP53 C275Y MISSENSE\n\ -TCGA-25-1635-01 TP53 D259Y MISSENSE\n\ -TCGA-13-1506-01 TP53 M66fs TRUNC\n\ -TCGA-24-1560-01 TP53 G244C MISSENSE\n\ -TCGA-13-1410-01 TP53 L130fs TRUNC\n\ -TCGA-13-0804-01 TP53 R273H MISSENSE\n\ -TCGA-24-1464-01 TP53 N239S MISSENSE\n\ -TCGA-10-0935-01 TP53 G187_splice TRUNC\n\ -TCGA-23-1032-01 TP53 R248Q MISSENSE\n\ -TCGA-25-1630-01 TP53 V173L MISSENSE\n\ -TCGA-61-2012-01 TP53 Y220C MISSENSE\n\ -TCGA-36-1568-01 TP53 G245S MISSENSE\n\ -TCGA-23-2072-01 TP53 Q331_splice TRUNC\n\ -TCGA-13-1487-01 TP53 M237K MISSENSE\n\ -TCGA-24-1426-01 TP53 R273C MISSENSE\n\ -TCGA-24-1470-01 TP53 S260fs TRUNC\n\ -TCGA-13-0920-01 TP53 Q100* TRUNC\n\ -TCGA-13-0761-01 TP53 R273H MISSENSE\n\ -TCGA-25-1320-01 TP53 C124fs TRUNC\n\ -TCGA-23-1021-01 TP53 A159V MISSENSE\n\ -TCGA-04-1348-01 TP53 G266R MISSENSE\n\ -TCGA-23-1027-01 TP53 E198* TRUNC\n\ -TCGA-04-1338-01 TP53 G245S MISSENSE\n\ -TCGA-23-1117-01 TP53 Q144fs TRUNC\n\ -TCGA-36-1578-01 TP53 R273H MISSENSE\n\ -TCGA-36-1575-01 TP53 R273H MISSENSE\n\ -TCGA-36-1574-01 TP53 R273H MISSENSE\n\ -TCGA-25-2399-01 TP53 R175H MISSENSE\n\ -TCGA-25-1634-01 TP53 A70fs TRUNC\n\ -TCGA-30-1891-01 TP53 L194R MISSENSE\n\ -TCGA-36-1577-01 TP53 E224_splice TRUNC\n\ -TCGA-13-0900-01 TP53 R273H MISSENSE\n\ -TCGA-24-1466-01 TP53 R249G MISSENSE\n\ -TCGA-61-2092-01 TP53 D208V MISSENSE\n\ -TCGA-04-1347-01 TP53 S215R MISSENSE\n\ -TCGA-20-0990-01 TP53 Q144* TRUNC\n\ -TCGA-13-1499-01 TP53 R273C MISSENSE\n\ -TCGA-24-1104-01 TP53 I195T MISSENSE\n\ -TCGA-24-1418-01 TP53 S227fs TRUNC\n\ -TCGA-57-1583-01 TP53 C229fs TRUNC\n\ -TCGA-29-2427-01 TP53 G244D MISSENSE\n\ -TCGA-13-1499-01 TP53 R248Q MISSENSE\n\ -TCGA-13-0795-01 TP53 C135Y MISSENSE\n\ -TCGA-13-1496-01 TP53 R248Q MISSENSE\n\ -TCGA-09-2045-01 TP53 H179R MISSENSE\n\ -TCGA-23-2081-01 TP53 G262V MISSENSE\n\ -TCGA-24-1474-01 TP53 Q192* TRUNC\n\ -TCGA-25-1623-01 TP53 R282W MISSENSE\n\ -TCGA-24-1551-01 TP53 R248W MISSENSE\n\ -TCGA-24-1431-01 TP53 Q192* TRUNC\n\ -TCGA-13-2060-01 TP53 H179R MISSENSE\n\ -TCGA-25-1631-01 TP53 T125_splice TRUNC\n\ -TCGA-13-0893-01 TP53 G245D MISSENSE\n\ -TCGA-13-1495-01 TP53 I195F MISSENSE\n\ -TCGA-24-1603-01 TP53 S315fs TRUNC\n\ -TCGA-04-1530-01 TP53 R273H MISSENSE\n\ -TCGA-04-1542-01 TP53 R273H MISSENSE\n\ -TCGA-24-1471-01 TP53 E271* TRUNC\n\ -TCGA-61-2102-01 TP53 G266R MISSENSE\n\ -TCGA-24-1469-01 TP53 I195T MISSENSE\n\ -TCGA-57-1584-01 TP53 C176Y MISSENSE\n\ -TCGA-13-1407-01 TP53 F109C MISSENSE\n\ -TCGA-13-1512-01 TP53 R273L MISSENSE\n\ -TCGA-23-1028-01 TP53 P250L MISSENSE\n\ -TCGA-13-0894-01 TP53 H193Y MISSENSE\n\ -TCGA-13-1409-01 TP53 S261_splice TRUNC\n\ -TCGA-24-0982-01 TP53 R248W MISSENSE\n\ -TCGA-36-1570-01 TP53 R248fs TRUNC\n\ -TCGA-13-0730-01 TP53 H178fs TRUNC\n\ -TCGA-61-2000-01 TP53 K132E MISSENSE\n\ -TCGA-61-2110-01 TP53 S127Y MISSENSE\n\ -TCGA-31-1950-01 TP53 I195T MISSENSE\n\ -TCGA-24-1424-01 TP53 I195T MISSENSE\n\ -TCGA-25-1632-01 TP53 R248G MISSENSE\n\ -TCGA-24-1427-01 TP53 V272fs TRUNC\n\ -TCGA-61-1998-01 TP53 S215R MISSENSE\n\ -TCGA-13-0904-01 TP53 G279E MISSENSE\n\ -TCGA-13-0923-01 TP53 G187_splice TRUNC\n\ -TCGA-24-1563-01 TP53 I195T MISSENSE\n\ -TCGA-13-1504-01 TP53 I251S MISSENSE\n\ -TCGA-25-1324-01 TP53 Y126_splice TRUNC\n\ -TCGA-13-0897-01 TP53 R283fs TRUNC\n\ -TCGA-04-1331-01 TP53 R306* TRUNC\n\ -TCGA-10-0937-01 TP53 R282W MISSENSE\n\ -TCGA-13-1405-01 TP53 R196* TRUNC\n\ -TCGA-04-1364-01 TP53 R248Q MISSENSE\n\ -TCGA-20-0991-01 TP53 S241F MISSENSE\n\ -TCGA-24-2267-01 TP53 T284fs TRUNC\n\ -TCGA-13-1404-01 TP53 C176Y MISSENSE\n\ -TCGA-13-0911-01 TP53 L43fs TRUNC\n\ -TCGA-25-1313-01 TP53 L145R MISSENSE\n\ -TCGA-36-1571-01 TP53 R337C MISSENSE\n\ -TCGA-13-0884-01 TP53 R342* TRUNC\n\ -TCGA-23-2078-01 TP53 T256del INFRAME\n\ -TCGA-13-1412-01 TP53 M237I MISSENSE\n\ -TCGA-24-1545-01 TP53 S241Y MISSENSE\n\ -TCGA-25-2401-01 TP53 L194R MISSENSE\n\ -TCGA-24-1436-01 TP53 Q331_splice TRUNC\n\ -TCGA-25-2400-01 TP53 E224_splice TRUNC\n\ -TCGA-04-1357-01 TP53 P223fs TRUNC\n\ -TCGA-13-1403-01 TP53 T125_splice TRUNC\n\ -TCGA-13-0886-01 TP53 V272M MISSENSE\n\ -TCGA-25-1318-01 TP53 R175H MISSENSE\n\ -TCGA-23-1116-01 TP53 S261_splice TRUNC\n\ -TCGA-10-0925-01\n\ -TCGA-10-0926-01\n\ -TCGA-10-0927-01\n\ -TCGA-10-0928-01\n\ -TCGA-10-0930-01\n\ -TCGA-10-0931-01\n\ -TCGA-10-0933-01\n\ -TCGA-10-0934-01\n\ -TCGA-20-1684-01\n\ -TCGA-20-1685-01\n\ -TCGA-20-1686-01\n\ -TCGA-20-1687-01\n\ -TCGA-23-1021-01\n\ -TCGA-23-1022-01\n\ -TCGA-23-1023-01\n\ -TCGA-23-1024-01\n\ -TCGA-23-1026-01\n\ -TCGA-23-1027-01\n\ -TCGA-23-1028-01\n\ -TCGA-23-1029-01\n\ -TCGA-23-1030-01\n\ -TCGA-23-1031-01\n\ -TCGA-23-1032-01\n\ -TCGA-23-1107-01\n\ -TCGA-23-1109-01\n\ -TCGA-23-1110-01\n\ -TCGA-23-1111-01\n\ -TCGA-23-1113-01\n\ -TCGA-23-1114-01\n\ -TCGA-23-1116-01\n\ -TCGA-23-1117-01\n\ -TCGA-23-1118-01\n\ -TCGA-23-1119-01\n\ -TCGA-23-1120-01\n\ -TCGA-23-1121-01\n\ -TCGA-23-1122-01\n\ -TCGA-23-1123-01\n\ -TCGA-23-1124-01\n\ -TCGA-23-1809-01\n\ -TCGA-23-2072-01\n\ -TCGA-23-2077-01\n\ -TCGA-23-2078-01\n\ -TCGA-23-2079-01\n\ -TCGA-23-2081-01\n\ -TCGA-23-2084-01\n\ -TCGA-23-2641-01\n\ -TCGA-23-2643-01\n\ -TCGA-23-2645-01\n\ -TCGA-23-2647-01\n\ -TCGA-23-2649-01\n\ -TCGA-24-0966-01\n\ -TCGA-24-0968-01\n\ -TCGA-24-0970-01\n\ -TCGA-24-0975-01\n\ -TCGA-24-0979-01\n\ -TCGA-24-0980-01\n\ -TCGA-24-0981-01\n\ -TCGA-24-0982-01\n\ -TCGA-24-1103-01\n\ -TCGA-24-1104-01\n\ -TCGA-24-1105-01\n\ -TCGA-24-1413-01\n\ -TCGA-24-1416-01\n\ -TCGA-24-1417-01\n\ -TCGA-24-1418-01\n\ -TCGA-24-1419-01\n\ -TCGA-24-1422-01\n\ -TCGA-24-1423-01\n\ -TCGA-24-1424-01\n\ -TCGA-24-1425-01\n\ -TCGA-24-1426-01\n\ -TCGA-24-1427-01\n\ -TCGA-24-1428-01\n\ -TCGA-24-1430-01\n\ -TCGA-24-1431-01\n\ -TCGA-24-1434-01\n\ -TCGA-24-1435-01\n\ -TCGA-24-1436-01\n\ -TCGA-24-1463-01\n\ -TCGA-24-1464-01\n\ -TCGA-24-1466-01\n\ -TCGA-24-1467-01\n\ -TCGA-24-1469-01\n\ -TCGA-24-1470-01\n\ -TCGA-24-1471-01\n\ -TCGA-24-1474-01\n\ -TCGA-24-1544-01\n\ -TCGA-24-1545-01\n\ -TCGA-24-1546-01\n\ -TCGA-24-1548-01\n\ -TCGA-24-1549-01\n\ -TCGA-24-1550-01\n\ -TCGA-24-1551-01\n\ -TCGA-24-1552-01\n\ -TCGA-24-1553-01\n\ -TCGA-24-1555-01\n\ -TCGA-24-1556-01\n\ -TCGA-24-1557-01\n\ -TCGA-24-1558-01\n\ -TCGA-24-1560-01\n\ -TCGA-24-1562-01\n\ -TCGA-24-1563-01\n\ -TCGA-24-1564-01\n\ -TCGA-24-1565-01\n\ -TCGA-24-1567-01\n\ -TCGA-24-1603-01\n\ -TCGA-24-1604-01\n\ -TCGA-24-1614-01\n\ -TCGA-24-1616-01\n\ -TCGA-24-1842-01\n\ -TCGA-24-1843-01\n\ -TCGA-24-1844-01\n\ -TCGA-24-1845-01\n\ -TCGA-24-1846-01\n\ -TCGA-24-1847-01\n\ -TCGA-24-1849-01\n\ -TCGA-24-1850-01\n\ -TCGA-24-1852-01\n\ -TCGA-24-1920-01\n\ -TCGA-24-1923-01\n\ -TCGA-24-1924-01\n\ -TCGA-24-1927-01\n\ -TCGA-24-1928-01\n\ -TCGA-24-1930-01\n\ -TCGA-24-2019-01\n\ -TCGA-24-2020-01\n\ -TCGA-24-2023-01\n\ -TCGA-24-2024-01\n\ -TCGA-24-2026-01\n\ -TCGA-24-2027-01\n\ -TCGA-24-2029-01\n\ -TCGA-24-2030-01\n\ -TCGA-24-2033-01\n\ -TCGA-24-2035-01\n\ -TCGA-24-2036-01\n\ -TCGA-24-2038-01\n\ -TCGA-24-2254-01\n\ -TCGA-24-2260-01\n\ -TCGA-24-2261-01\n\ -TCGA-24-2262-01\n\ -TCGA-24-2267-01\n\ -TCGA-24-2271-01\n\ -TCGA-24-2280-01\n\ -TCGA-24-2281-01\n\ -TCGA-24-2288-01\n\ -TCGA-24-2289-01\n\ -TCGA-24-2290-01\n\ -TCGA-24-2293-01\n\ -TCGA-24-2295-01\n\ -TCGA-24-2297-01\n\ -TCGA-24-2298-01\n\ -TCGA-25-1312-01\n\ -TCGA-25-1313-01\n\ -TCGA-25-1314-01\n\ -TCGA-25-1315-01\n\ -TCGA-25-1316-01\n\ -TCGA-25-1317-01\n\ -TCGA-25-1318-01\n\ -TCGA-25-1319-01\n\ -TCGA-25-1320-01\n\ -TCGA-25-1321-01\n\ -TCGA-25-1322-01\n\ -TCGA-25-1323-01\n\ -TCGA-25-1324-01\n\ -TCGA-25-1325-01\n\ -TCGA-25-1326-01\n\ -TCGA-25-1328-01\n\ -TCGA-25-1329-01\n\ -TCGA-25-1623-01\n\ -TCGA-25-1625-01\n\ -TCGA-25-1626-01\n\ -TCGA-25-1627-01\n\ -TCGA-25-1628-01\n\ -TCGA-25-1630-01\n\ -TCGA-25-1631-01\n\ -TCGA-25-1632-01\n\ -TCGA-25-1633-01\n\ -TCGA-25-1634-01\n\ -TCGA-25-1635-01\n\ -TCGA-25-1870-01\n\ -TCGA-25-1871-01\n\ -TCGA-25-1877-01\n\ -TCGA-25-1878-01\n\ -TCGA-25-2042-01\n\ -TCGA-25-2390-01\n\ -TCGA-25-2391-01\n\ -TCGA-25-2396-01\n\ -TCGA-25-2397-01\n\ -TCGA-25-2398-01\n\ -TCGA-25-2399-01\n\ -TCGA-25-2400-01\n\ -TCGA-25-2401-01\n\ -TCGA-25-2392-01\n\ -TCGA-25-2393-01\n\ diff --git a/src/main/resources/webapp/jsp/oncoprint/legend-template.jsp b/src/main/resources/webapp/jsp/oncoprint/legend-template.jsp deleted file mode 100644 index 3d84159f5f2..00000000000 --- a/src/main/resources/webapp/jsp/oncoprint/legend-template.jsp +++ /dev/null @@ -1,47 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - - diff --git a/src/main/resources/webapp/jsp/oncoprint/main.jsp b/src/main/resources/webapp/jsp/oncoprint/main.jsp deleted file mode 100644 index f48c36a4c25..00000000000 --- a/src/main/resources/webapp/jsp/oncoprint/main.jsp +++ /dev/null @@ -1,77 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. ---%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.util.GlobalProperties" %> -<%@ page import="org.mskcc.cbio.portal.dao.DaoMutation" %> -<%@ page import="org.mskcc.cbio.portal.servlet.QueryBuilder" %> -<%@ page import="java.util.List" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> - - - - -
-
\ No newline at end of file diff --git a/src/main/resources/webapp/jsp/oncoprint/mutation-file-example.txt b/src/main/resources/webapp/jsp/oncoprint/mutation-file-example.txt deleted file mode 100644 index 7441b607f99..00000000000 --- a/src/main/resources/webapp/jsp/oncoprint/mutation-file-example.txt +++ /dev/null @@ -1,15 +0,0 @@ -Hugo_Symbol Entrez_Gene_Id sample_id Protein_Change -BRCA1 672 TCGA-04-1357 Q1538* -BRCA1 672 TCGA-13-0730 R1835* -BRCA1 672 TCGA-23-1026 G813fs -BRCA1 672 TCGA-24-2035 G1710fs -BRCA1 672 TCGA-25-1625 E116* -BRCA1 672 TCGA-25-1630 K519fs -BRCA1 672 TCGA-25-1632 L1216fs -BRCA1 672 TCGA-29-2427 L431* -BRCA2 675 TCGA-13-0890 V1229fs -BRCA2 675 TCGA-13-1481 L2696fs -BRCA2 675 TCGA-23-1120 L3277fs -BRCA2 675 TCGA-24-1103 K1638E -BRCA2 675 TCGA-24-1555 T2607fs -BRCA2 675 TCGA-24-1562 K3326* diff --git a/src/main/resources/webapp/jsp/pancancer_study_summary.jsp b/src/main/resources/webapp/jsp/pancancer_study_summary.jsp deleted file mode 100644 index e291b791f14..00000000000 --- a/src/main/resources/webapp/jsp/pancancer_study_summary.jsp +++ /dev/null @@ -1,92 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%-- - - This is the main page for loading the pan-cancer study view, - - where "pan-cancer study" = a study comprising more than 1 cancer type. - --%> - - -<%@ page import="org.mskcc.cbio.portal.util.GlobalProperties" %> - - - -<%@ include file="src/main/webapp/jsp/pancancer_study_summary/pancancer_study_summary_templates.html" %> - - - - - -
- -
- - - - diff --git a/src/main/resources/webapp/jsp/pancancer_study_summary/pancancer_study_summary_templates.html b/src/main/resources/webapp/jsp/pancancer_study_summary/pancancer_study_summary_templates.html deleted file mode 100644 index 8248a292e14..00000000000 --- a/src/main/resources/webapp/jsp/pancancer_study_summary/pancancer_study_summary_templates.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/webapp/jsp/patient_view/clinical_timeline.jsp b/src/main/resources/webapp/jsp/patient_view/clinical_timeline.jsp deleted file mode 100644 index af5b32af765..00000000000 --- a/src/main/resources/webapp/jsp/patient_view/clinical_timeline.jsp +++ /dev/null @@ -1,248 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - - -<%@ page import="org.mskcc.cbio.portal.util.GlobalProperties" %> - - - - - - - -
- Clinical Events -
-
- -
-
-
diff --git a/src/main/resources/webapp/jsp/patient_view/cna.jsp b/src/main/resources/webapp/jsp/patient_view/cna.jsp deleted file mode 100644 index 9e30f255ed4..00000000000 --- a/src/main/resources/webapp/jsp/patient_view/cna.jsp +++ /dev/null @@ -1,596 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.servlet.PatientView" %> -<%@ page import="org.mskcc.cbio.portal.servlet.CnaJSON" %> - - - -
loading
-
The following table contains filtered copy number alterations (CNAs). -
- - - - - -
- - <%@ include file="src/main/webapp/jsp/patient_view/cna_table_template.jsp"%> -
-
diff --git a/src/main/resources/webapp/jsp/patient_view/cna_table_template.jsp b/src/main/resources/webapp/jsp/patient_view/cna_table_template.jsp deleted file mode 100644 index c28bbb31a15..00000000000 --- a/src/main/resources/webapp/jsp/patient_view/cna_table_template.jsp +++ /dev/null @@ -1,46 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - - -
CNA Event IDTumorsGeneCNAAnnotationCytobandmRNA Expr.CohortDrugs
- - - - - - - - - -
Drug NameDrug Target(s)DescriptionFDA approved?Data Sources
-
loading
diff --git a/src/main/resources/webapp/jsp/patient_view/mdacc_patient_heatmap_viewer.jsp b/src/main/resources/webapp/jsp/patient_view/mdacc_patient_heatmap_viewer.jsp deleted file mode 100644 index 9c714a072c2..00000000000 --- a/src/main/resources/webapp/jsp/patient_view/mdacc_patient_heatmap_viewer.jsp +++ /dev/null @@ -1,104 +0,0 @@ -<%-- - - Copyright (c) 2016 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - - -<%-- For the PATIENT view --%> - -<%@ page import="org.mskcc.cbio.portal.util.GlobalProperties" %> - - - - -
\ No newline at end of file diff --git a/src/main/resources/webapp/jsp/patient_view/mutations.jsp b/src/main/resources/webapp/jsp/patient_view/mutations.jsp deleted file mode 100644 index 4b25b3421f6..00000000000 --- a/src/main/resources/webapp/jsp/patient_view/mutations.jsp +++ /dev/null @@ -1,1321 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.dao.DaoMutSig" %> -<%@ page import="org.mskcc.cbio.portal.servlet.MutationsJSON" %> -<%@ page import="org.mskcc.cbio.portal.servlet.PatientView" %> - - - - - - - -
loading
-
The following table contains filtered mutations. -
-
- - - - - diff --git a/src/main/resources/webapp/jsp/patient_view/mutations_table_template.jsp b/src/main/resources/webapp/jsp/patient_view/mutations_table_template.jsp deleted file mode 100644 index cb6c2e22ad7..00000000000 --- a/src/main/resources/webapp/jsp/patient_view/mutations_table_template.jsp +++ /dev/null @@ -1,63 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - - - - - Mutation Event ID - Tumors - Gene - Protein
Change
- Annotation - Chr - Start - End - Ref - Var - Validation - Type - Allele
Freq
- Variant
Reads
- Ref
Reads
- Allele
Freq (N)
- Variant
Reads (N)
- Ref
Reads (N)
- BAM - Copy # - mRNA Expr. - Cohort - cBioPortal - COSMIC - Mutation
Assessor
- Drugs - - diff --git a/src/main/resources/webapp/jsp/patient_view/path_report.jsp b/src/main/resources/webapp/jsp/patient_view/path_report.jsp deleted file mode 100644 index c591d4b3fb5..00000000000 --- a/src/main/resources/webapp/jsp/patient_view/path_report.jsp +++ /dev/null @@ -1,53 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - - - - -

It appears you don't have a PDF plugin for this browser.

-

You can click here to - download the pathology report PDF file.

- -
- - diff --git a/src/main/resources/webapp/jsp/patient_view/pathways.jsp b/src/main/resources/webapp/jsp/patient_view/pathways.jsp deleted file mode 100644 index 1bd3c6c58a6..00000000000 --- a/src/main/resources/webapp/jsp/patient_view/pathways.jsp +++ /dev/null @@ -1,76 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<% -request.setAttribute("include_network_help_tab", Boolean.FALSE); -request.setAttribute("include_network_legend", Boolean.FALSE); -%> - - - - - - - - - - - diff --git a/src/main/resources/webapp/jsp/patient_view/patient_view.jsp b/src/main/resources/webapp/jsp/patient_view/patient_view.jsp deleted file mode 100644 index 3e3dcbdb99c..00000000000 --- a/src/main/resources/webapp/jsp/patient_view/patient_view.jsp +++ /dev/null @@ -1,69 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.servlet.QueryBuilder" %> -<%@ page import="org.mskcc.cbio.portal.servlet.PatientView" %> -<%@ page import="org.mskcc.cbio.portal.servlet.DrugsJSON" %> -<%@ page import="org.mskcc.cbio.portal.servlet.ServletXssUtil" %> -<%@ page import="org.mskcc.cbio.portal.servlet.CheckDarwinAccessServlet" %> -<%@ page import="org.mskcc.cbio.portal.model.CancerStudy" %> -<%@ page import="org.mskcc.cbio.portal.model.GeneticProfile" %> -<%@ page import="org.mskcc.cbio.portal.util.GlobalProperties" %> -<%@ page import="java.util.HashMap" %> -<%@ page import="java.util.Map" %> -<%@ page import="java.util.Set" %> -<%@ page import= "java.net.URL" %> -<%@ page import="org.apache.commons.lang3.StringUtils" %> -<%@ page import="com.fasterxml.jackson.databind.ObjectMapper" %> -<%@ page import="org.mskcc.cbio.portal.util.GlobalProperties" %> -<%@ page import="org.mskcc.cbio.portal.util.IGVLinking" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> -<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> - - - - <%@taglib prefix="t" tagdir="/WEB-INF/tags" %> - - - - - - - - -
-
- -
diff --git a/src/main/resources/webapp/jsp/patient_view/samples_table.jsp b/src/main/resources/webapp/jsp/patient_view/samples_table.jsp deleted file mode 100644 index c0963d21bdc..00000000000 --- a/src/main/resources/webapp/jsp/patient_view/samples_table.jsp +++ /dev/null @@ -1,68 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%-- - ~ Copyright (c) 2012 Memorial Sloan-Kettering Cancer Center. - ~ This library is free software; you can redistribute it and/or modify it - ~ under the terms of the GNU Lesser General Public License as published - ~ by the Free Software Foundation; either version 2.1 of the License, or - ~ any later version. - ~ - ~ This library is distributed in the hope that it will be useful, but - ~ WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF - ~ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. The software and - ~ documentation provided hereunder is on an "as is" basis, and - ~ Memorial Sloan-Kettering Cancer Center - ~ has no obligations to provide maintenance, support, - ~ updates, enhancements or modifications. In no event shall - ~ Memorial Sloan-Kettering Cancer Center - ~ be liable to any party for direct, indirect, special, - ~ incidental or consequential damages, including lost profits, arising - ~ out of the use of this software and its documentation, even if - ~ Memorial Sloan-Kettering Cancer Center - ~ has been advised of the possibility of such damage. See - ~ the GNU Lesser General Public License for more details. - ~ - ~ You should have received a copy of the GNU Lesser General Public License - ~ along with this library; if not, write to the Free Software Foundation, - ~ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - --%> - -<%@ page import="org.mskcc.cbio.portal.dao.DaoTypeOfCancer" %> -<%@ page import="org.mskcc.cbio.portal.model.TypeOfCancer" %> -<%@ page import="org.mskcc.cbio.portal.dao.DaoException" %><% - String cancerTypeId = cancerStudy.getTypeOfCancerId().trim(); - TypeOfCancer typeOfCancerById = DaoTypeOfCancer.getTypeOfCancerById(cancerTypeId); -%> - - -
diff --git a/src/main/resources/webapp/jsp/patient_view/similar_patients.jsp b/src/main/resources/webapp/jsp/patient_view/similar_patients.jsp deleted file mode 100644 index c615afec423..00000000000 --- a/src/main/resources/webapp/jsp/patient_view/similar_patients.jsp +++ /dev/null @@ -1,187 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.servlet.SimilarPatientsJSON" %> - -<%if(showPlaceHoder){%> -A genomic overview with events aligned across patients goes here... -<%}%> - - - -
loading
- - - - - -
- - - - - - - - -
PatientCancer StudyShared Events of Interest
-
\ No newline at end of file diff --git a/src/main/resources/webapp/jsp/patient_view/summary.jsp b/src/main/resources/webapp/jsp/patient_view/summary.jsp deleted file mode 100644 index d1dc8ff3905..00000000000 --- a/src/main/resources/webapp/jsp/patient_view/summary.jsp +++ /dev/null @@ -1,295 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.servlet.CnaJSON" %> -<%@ page import="org.mskcc.cbio.portal.dao.DaoSample" %> -<%@ page import="org.mskcc.cbio.portal.model.Sample" %> -<%@ page import="java.util.ArrayList" %> -<%@ page import="java.util.List" %> -<%@ page import="org.mskcc.cbio.portal.util.GlobalProperties" %> - - - - - - - - - - - - -<%if(showTimeline){%> - -
-<%}%> - -<%if(showGenomicOverview){%> -
-Genomic Overview - - - - <%if(hasAlleleFrequencyData && caseIds.size() > 1) {%> - - <%} else {%> - - <%}%> - -
- - - -
- -
-
- -
- - -
-
-<%}%> -<%if(hasAlleleFrequencyData && caseIds.size() >= 1) {%> - - -<%}%> - - - -<%if(showMutations){%> - - - -<%}if(showCNA){%> - - - -<%}%> -
-
loading Loading mutations ...
- - - - - -
-
-
loading Loading copy number alterations ...
- - - - -
- - <%@ include file="src/main/webapp/jsp/patient_view/cna_table_template.jsp"%> -
-
-
diff --git a/src/main/resources/webapp/jsp/patient_view/tissue_images.jsp b/src/main/resources/webapp/jsp/patient_view/tissue_images.jsp deleted file mode 100644 index 88ec048af04..00000000000 --- a/src/main/resources/webapp/jsp/patient_view/tissue_images.jsp +++ /dev/null @@ -1,47 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - - - - -
loading
\ No newline at end of file diff --git a/src/main/resources/webapp/jsp/plots_tab.jsp b/src/main/resources/webapp/jsp/plots_tab.jsp deleted file mode 100644 index 3b4579cb758..00000000000 --- a/src/main/resources/webapp/jsp/plots_tab.jsp +++ /dev/null @@ -1,193 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.model.GeneWithScore" %> -<%@ page import="org.mskcc.cbio.portal.servlet.QueryBuilder" %> -<%@ page import="java.util.ArrayList" %> -<%@ page import="java.io.PrintWriter" %> -<%@ page import="java.io.IOException" %> -<%@ page import="org.mskcc.cbio.portal.model.GeneticProfile" %> -<%@ page import="org.mskcc.cbio.portal.model.GeneticAlterationType" %> - - - - - - - - - - - - - - - - - - - - - -
-
-
- - - - diff --git a/src/main/resources/webapp/jsp/preview.jsp b/src/main/resources/webapp/jsp/preview.jsp deleted file mode 100644 index f8be9dc89f1..00000000000 --- a/src/main/resources/webapp/jsp/preview.jsp +++ /dev/null @@ -1,198 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - - - -
-
    -
  • - Cross cancer query of CDKN2A -
  • -
  • - Patient-specific view for a TCGA endometrial cancer case -
  • -
  • - Network of genomic alterations in Serous Ovarian Cancer -
  • -
  • - EGFR Amplifications in Gliobastoma -
  • -
  • - Survival Analysis of BRCA Mutated v. Non-BRCA Mutated in Serous Ovarian Cancer -
  • -
  • - Epigenetic Silencing of BRCA1 in Serous Ovarian Cancer -
  • -
  • - Structural view of a PIK3R1 mutation in Glioblastoma -
  • -
  • - TP53 mutations in ovarian cancer -
  • -
-
- - \ No newline at end of file diff --git a/src/main/resources/webapp/jsp/preview_su2c.jsp b/src/main/resources/webapp/jsp/preview_su2c.jsp deleted file mode 100644 index 641d2201c49..00000000000 --- a/src/main/resources/webapp/jsp/preview_su2c.jsp +++ /dev/null @@ -1,113 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - - - -
-
    -
  • - Survival Analysis of BRCA Mutated v. Non-BRCA Mutated in Serous Ovarian Cancer -
  • -
  • - Epigenetic Silencing of BRCA1 in Serous Ovarian Cancer -
  • -
  • - TP53 mutations in ovarian cancer -
  • -
-
- - \ No newline at end of file diff --git a/src/main/resources/webapp/jsp/query_form.jsp b/src/main/resources/webapp/jsp/query_form.jsp deleted file mode 100644 index de1a36df7fc..00000000000 --- a/src/main/resources/webapp/jsp/query_form.jsp +++ /dev/null @@ -1,226 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.servlet.*" %> -<%@ page import="org.mskcc.cbio.portal.util.XssRequestWrapper" %> -<%@ page import="java.util.HashSet" %> -<%@ page import="java.io.IOException" %> -<%@ page import="java.net.URLEncoder" %> -<%@ page import="org.apache.commons.lang3.*" %> -<%@ page import="org.mskcc.cbio.portal.util.GlobalProperties" %> -<%@ page import="java.util.ArrayList" %> -<%@ page import="java.util.Map" %> -<%@ page import="java.util.Set" %> -<%@ page import="java.util.List" %> - -<% - org.mskcc.cbio.portal.servlet.ServletXssUtil localXssUtil = ServletXssUtil.getInstance(); - String localCancerTypeId = - (String) request.getAttribute(QueryBuilder.CANCER_STUDY_ID); - String localSampleSetId = - (String) request.getAttribute(QueryBuilder.CASE_SET_ID); - String localCancerStudyList = (String) request.getParameter(QueryBuilder.CANCER_STUDY_LIST); - if (localCancerStudyList == null) { - localCancerStudyList = ""; - } - HashSet localGeneticProfileIdSet = (HashSet) request.getAttribute - (QueryBuilder.GENETIC_PROFILE_IDS); - String localCaseIds = request.getParameter(QueryBuilder.CASE_IDS); - //String localGeneList = localXssUtil.getCleanInput(request, QueryBuilder.GENE_LIST); - String localGeneList = request.getParameter(QueryBuilder.GENE_LIST); - - if (request instanceof XssRequestWrapper) - { - localGeneList = localXssUtil.getCleanInput( - ((XssRequestWrapper)request).getRawParameter(QueryBuilder.GENE_LIST)); - } - - String localTabIndex = request.getParameter(QueryBuilder.TAB_INDEX); - String localzScoreThreshold = request.getParameter(QueryBuilder.Z_SCORE_THRESHOLD); - if (localzScoreThreshold == null) { - localzScoreThreshold = "2.0"; - } - String localRppaScoreThreshold = request.getParameter(QueryBuilder.RPPA_SCORE_THRESHOLD); - if (localRppaScoreThreshold == null) { - localRppaScoreThreshold = "2.0"; - } - if (localTabIndex == null) { - localTabIndex = QueryBuilder.TAB_VISUALIZE; - } else { - localTabIndex = URLEncoder.encode(localTabIndex); - } - - String localGeneSetChoice = request.getParameter(QueryBuilder.GENE_SET_CHOICE); - //String clientTranspose = localXssUtil.getCleanInput(request, QueryBuilder.CLIENT_TRANSPOSE_MATRIX); - String clientTranspose = request.getParameter(QueryBuilder.CLIENT_TRANSPOSE_MATRIX); - if (localGeneSetChoice == null) { - localGeneSetChoice = "user-defined-list"; - } - // Get prioritized studies for study selector - - List priorityStudies = GlobalProperties.getPriorityStudies(); -%> - -<% - /** - * Put together global parameters - * - */ -// HashSet geneticProfileIdSet = -// (HashSet) request.getAttribute(QueryBuilder.GENETIC_PROFILE_IDS); - - // put geneticProfileIds into the proper form for the JSON request -// HashSet geneticProfileIdSet = (HashSet) request.getAttribute -// (QueryBuilder.GENETIC_PROFILE_IDS); -// String geneticProfiles = StringUtils.join(geneticProfileIdSet.iterator(), " "); -// geneticProfiles = geneticProfiles.trim(); -// -// // put gene string into a form that javascript can swallow -// String genes = (String) request.getAttribute(QueryBuilder.RAW_GENE_STR); -// genes = StringEscapeUtils.escapeEcmaScript(genes); -// -// // get cases -// String cases = (String) request.getAttribute(QueryBuilder.SET_OF_CASE_IDS); -// cases = StringEscapeUtils.escapeEcmaScript(cases); -// -// String caseSetId = (String) request.getAttribute(QueryBuilder.CASE_SET_ID); -// String caseIdsKey = (String) request.getAttribute(QueryBuilder.CASE_IDS_KEY); -%> - - - -
-
-
- <%@ include file="src/main/webapp/jsp/step1_json.jsp" %> - <%@ include file="src/main/webapp/jsp/step2_json.jsp" %> - <%@ include file="src/main/webapp/jsp/step3_json.jsp" %> - <%@ include file="src/main/webapp/jsp/step4_json.jsp" %> - <%@ include file="src/main/webapp/jsp/step5_json.jsp" %> - - -

- <% conditionallyOutputTransposeMatrixOption (localTabIndex, clientTranspose, out); %> -

-

- - <% conditionallyOutputGenomespaceOption(localTabIndex, out); %> -

-
-
-
- -<%! - private void conditionallyOutputTransposeMatrixOption(String localTabIndex, - String clientTranspose, JspWriter out) - throws IOException { - if (localTabIndex.equals(QueryBuilder.TAB_DOWNLOAD)) { - outputTransposeMatrixOption(clientTranspose, out); - } - } - - private void outputTransposeMatrixOption(String clientTranspose, JspWriter out) throws IOException { - String checked = hasUserSelectedTheTransposeOption(clientTranspose); - out.println (" Clicking submit will generate a tab-delimited file " - + " containing your requested data."); - out.println ("
"); - } - - private String hasUserSelectedTheTransposeOption(String clientTranspose) { - if (clientTranspose != null) { - return "checked"; - } else { - return ""; - } - } - - private void conditionallyOutputGenomespaceOption(String localTabIndex, JspWriter out) - throws IOException { - if (GlobalProperties.genomespaceEnabled() && localTabIndex.equals(QueryBuilder.TAB_DOWNLOAD)) { - out.println("\"Send"); - } - } -%> diff --git a/src/main/resources/webapp/jsp/step1_json.jsp b/src/main/resources/webapp/jsp/step1_json.jsp deleted file mode 100644 index 7eb9b990316..00000000000 --- a/src/main/resources/webapp/jsp/step1_json.jsp +++ /dev/null @@ -1,149 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@taglib prefix="s" uri="http://www.springframework.org/tags" %> - -<% - String step1ErrorMsg = (String) request.getAttribute(QueryBuilder.STEP1_ERROR_MSG); -%> -
- Select Cancer Study: -
-
- - -
- - <%-- loop over the configured query suggestions --%> - -
-
-
- No studies selected. - Deselect all -
- - - -
- - - - - - -
-
- - - - - - -<% -if (step1ErrorMsg != null) { - out.println("
" - + "" - + "" + step1ErrorMsg + ""); -} -%> - -<% -if (step1ErrorMsg != null) { - out.println ("
"); -} -%> - -
- diff --git a/src/main/resources/webapp/jsp/step2_json.jsp b/src/main/resources/webapp/jsp/step2_json.jsp deleted file mode 100644 index 29eabbfa7ee..00000000000 --- a/src/main/resources/webapp/jsp/step2_json.jsp +++ /dev/null @@ -1,89 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.servlet.QueryBuilder" %> -<%@ page import="static org.mskcc.cbio.portal.servlet.QueryBuilder.DATA_PRIORITY" %> -<% - String step2ErrorMsg = (String) request.getAttribute(QueryBuilder.STEP2_ERROR_MSG); -%> - -
- Select Genomic Profiles: - -<% -if (step2ErrorMsg != null) { - out.println("
" - + "" - + "" + step2ErrorMsg + ""); -} -%> - -
-
- -<% -if (step2ErrorMsg != null) { - out.println ("
"); -} -%> - -
- - -<% - Integer priority; - try { - priority = Integer.parseInt(request.getParameter(DATA_PRIORITY)); - } catch (NumberFormatException e) { - priority = 0; - } - - String checked[] = {"", "", ""}; - if(priority == null) - priority = 0; - - checked[priority] = " checked"; -%> - -
- Select Data Type Priority: - > - - - > - - - > - -
- - diff --git a/src/main/resources/webapp/jsp/step3_json.jsp b/src/main/resources/webapp/jsp/step3_json.jsp deleted file mode 100644 index 188f2d72dae..00000000000 --- a/src/main/resources/webapp/jsp/step3_json.jsp +++ /dev/null @@ -1,205 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.servlet.QueryBuilder" %> -<% - String step3ErrorMsg = (String) request.getAttribute(QueryBuilder.STEP3_ERROR_MSG); -%> - -
- - - - - - - - - - - -
- Select Patient/Case Set: - - - - -
- -
- -
- - - - - - - - - - - - - -
Build a Custom Case Set for: Number of Matching Cases:
 
-
- - - - - - -
- -
- loading - - - - - - - - - - - -
Gene SymbolNum MutationsQ-ValueAll
- -
- -
-
loading
-
- -
- - -<% -String customCaseListStyle = "none"; -// Output step 3 form validation error -if (step3ErrorMsg != null) { - out.println("
" - + "" - + "" + step3ErrorMsg + ""); - customCaseListStyle = "block"; -} -%> -
-

Enter case IDs below:

- -
-By sample ID -
-By patient ID -
- -<% -if (step3ErrorMsg != null) { - out.println("
"); -} -%> -
diff --git a/src/main/resources/webapp/jsp/step4_json.jsp b/src/main/resources/webapp/jsp/step4_json.jsp deleted file mode 100644 index 52b8f554798..00000000000 --- a/src/main/resources/webapp/jsp/step4_json.jsp +++ /dev/null @@ -1,87 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%@ page import="org.mskcc.cbio.portal.servlet.QueryBuilder" %> -<% - String step4ErrorMsg = (String) request.getAttribute(QueryBuilder.STEP4_ERROR_MSG); -%> - -
- Enter Gene Set: - - - - <% if (localTabIndex.equals(QueryBuilder.TAB_VISUALIZE)) { %> - <% out.println("      Advanced: Onco Query Language (OQL)"); %> - <% } %> - -
- -
- -
- - -
- - - - - -

- -
- diff --git a/src/main/resources/webapp/jsp/step5_json.jsp b/src/main/resources/webapp/jsp/step5_json.jsp deleted file mode 100644 index f792df2ec7f..00000000000 --- a/src/main/resources/webapp/jsp/step5_json.jsp +++ /dev/null @@ -1,48 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<% - if (localTabIndex != null && localTabIndex.equals(QueryBuilder.TAB_VISUALIZE)) { -%> - -<% } %> \ No newline at end of file diff --git a/src/main/resources/webapp/jsp/survival_tab.jsp b/src/main/resources/webapp/jsp/survival_tab.jsp deleted file mode 100644 index a4682dc5b55..00000000000 --- a/src/main/resources/webapp/jsp/survival_tab.jsp +++ /dev/null @@ -1,63 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -
-
-
- - \ No newline at end of file diff --git a/src/main/resources/webapp/jsp/testimonials.jsp b/src/main/resources/webapp/jsp/testimonials.jsp deleted file mode 100644 index c39ed26d13b..00000000000 --- a/src/main/resources/webapp/jsp/testimonials.jsp +++ /dev/null @@ -1,108 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - -<%-- - Created by IntelliJ IDEA. - User: byrne - Date: Dec 2, 2011 - Time: 12:16:49 PM - To change this template use File | Settings | File Templates. ---%> -<%@ page contentType="text/html;charset=UTF-8" language="java" %> - -
-
-

"Whenever bench scientists ask me how they can look at TCGA data, I've never - had a good answer for them. Now I do. The cBio Portal meets a critical need--it is the - interface that the cancer research community needs to access the wealth of TCGA. Even as a - computational biologist, I use it to follow-up on genes of interest. It makes querying - the data much less painful." -

- – Postdoctoral Fellow, Oregon Health & Science University -
-
-

"I would like to congratulate you and the team of the cBio portal. - It's just an amazing tool to work with, and we at Mass General really appreciate it." -

- – Research Fellow at Massachusetts General Hospital -
- -
-

"As a bench biologist with primary aim of determining gene aberrations in GBM, I found - your site absolutely fantastic! Thank you! I have to reiterate how awesome and user-friendly - your group has made this site - finally accomplishing the goal of having data easily accessible - and meaningful." -

- – Sr. Research Associate at Knight Cancer Institute/OHSU -
- -
-

"Thank you for your incredible resource that has helped greatly in accessing the TCGA - genomics data." -

- – Postdoctoral Fellow, Johns Hopkins University School of Medicine, - Dept Radiation Oncology and Molecular Radiation Sciences - -
- -
-

"I have been enjoying the ease with which TCGA data can be extracted in R using your CGDS package. - Very nice work!" -

- – Sr. Software Engineer, Institute for Systems Biology -
- -
-

"Thank you for generating such an excellent software. It is very useful for our research." -

- – Research Fellow, Memorial Sloan-Kettering Cancer Center -
- -
-

"Thank you very much for providing and maintaining this great resource." -

- – Scientist, Discovery Bioinformatics, Biotechnology Company -
- -
-

"I want to thank you for the nice, useful and user-friendly interface you have generated - and shared with the community." -

- – Postdoctoral Fellow, Harvard Medical School, Children's Hospital Boston -
- -
-

"This portal is truly the greatest thing since sliced bread. I am making discoveries with it not only in glioblastoma, my primary focus, but in other cancers as well -- it's all so easy with this fantastic tool. And I am enjoying showing it to my colleagues, whose jaws also drop. Thank you a thousand times over for this beautiful public resource. I am looking forward to citing this soon in an upcoming paper..." -

- – Associate Professor, University of Virginia -
-
diff --git a/src/main/resources/webapp/jsp/visualize.jsp b/src/main/resources/webapp/jsp/visualize.jsp deleted file mode 100644 index 6c0bdc19499..00000000000 --- a/src/main/resources/webapp/jsp/visualize.jsp +++ /dev/null @@ -1,575 +0,0 @@ -<%-- - - Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. - - - - This library is distributed in the hope that it will be useful, but WITHOUT - - ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS - - FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder - - is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no - - obligations to provide maintenance, support, updates, enhancements or - - modifications. In no event shall Memorial Sloan-Kettering Cancer Center be - - liable to any party for direct, indirect, special, incidental or - - consequential damages, including lost profits, arising out of the use of this - - software and its documentation, even if Memorial Sloan-Kettering Cancer - - Center has been advised of the possibility of such damage. - --%> - -<%@page import="java.net.URLDecoder"%> -<%-- - - This file is part of cBioPortal. - - - - cBioPortal is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see . ---%> - - - - -<%@ include file="src/main/webapp/jsp/global/global_variables.jsp" %> - - - - - - -<%@ page import="java.util.Map" %> - -<% - // we have session service running AND this was a post, - // then modify URL to include session service id so bookmarking will work - if (useSessionServiceBookmark && "POST".equals(request.getMethod())) { -%> - -<% } // end if isPost and we have session service running %> - -
-
-
-
- -
-
    - <% - Boolean showMutTab = false; - Boolean showCancerTypesSummary = false; - Boolean showEnrichmentsTab = true; - Boolean showSurvivalTab = true; - Boolean showPlotsTab = true; - Boolean showDownloadTab = true; - Boolean showBookmarkTab = true; - List disabledTabs = GlobalProperties.getDisabledTabs(); - - Enumeration paramEnum = request.getParameterNames(); - StringBuffer buf = new StringBuffer(request.getAttribute(QueryBuilder.ATTRIBUTE_URL_BEFORE_FORWARDING) + "?"); - - while (paramEnum.hasMoreElements()) - { - String paramName = (String) paramEnum.nextElement(); - String values[] = request.getParameterValues(paramName); - - if (values != null && values.length >0) - { - for (int i=0; i' if we decide to add this - // parameter in the future - continue; - } - - // this is required to prevent XSS attacks - currentValue = xssUtil.getCleanInput(currentValue); - //currentValue = StringEscapeUtils.escapeEcmaScript(currentValue); - //currentValue = StringEscapeUtils.escapeHtml(currentValue); - currentValue = URLEncoder.encode(currentValue); - - buf.append (paramName + "=" + currentValue + "&"); - } - } - } - - if(isVirtualStudy){ - showCoexpTab = false; - showIGVtab = false; - showEnrichmentsTab = false; - has_survival = false; - includeNetworks = false; - showPlotsTab = false; - } - if(geneticProfiles.contains("mutation")) { - // hacky but consistent with how currently being done - showMutTab = true; - } - String[] geneList = URLDecoder.decode((String) request.getAttribute(QueryBuilder.GENE_LIST), "UTF-8").split("( )|(\\n)|(;)"); - if (geneList.length <= 1) { - computeLogOddsRatio = false; - } - - // determine whether to show the cancerTypesSummaryTab - // retrieve the cancerTypesMap and create an iterator for the values - showCancerTypesSummary = (Boolean) request.getAttribute(QueryBuilder.HAS_CANCER_TYPES); - - out.println ("
  • OncoPrint
  • "); - // if showCancerTypesSummary is try, add the list item - if(showCancerTypesSummary){ - out.println ("
  • Cancer Types Summary
  • "); - } - - if (computeLogOddsRatio) { - out.println ("
  • " - + "Mutual Exclusivity
  • "); - } - if (showPlotsTab) { - out.println ("
  • Plots
  • "); - } else { - out.println ("
  • Expression
  • "); - } - if (showMutTab){ - out.println ("
  • Mutations
  • "); - } - if (showCoexpTab) { - out.println ("
  • Co-Expression
  • "); - } - if ((has_mrna || has_copy_no || showMutTab && showEnrichmentsTab) && !isVirtualStudy) { - out.println("
  • Enrichments
  • "); - } - if (has_survival) { - out.println ("
  • Survival
  • "); - } - if (includeNetworks) { - out.println ("
  • Network
  • "); - } - if (showIGVtab){ - out.println ("
  • CN Segments
  • "); - } - if (showDownloadTab) { - out.println ("
  • Download
  • "); - } - if (showBookmarkTab) { - out.print ("
  • Bookmark
  • "); - } - out.println ("
"); - %> - -
- -
- -
- <% //contents of fingerprint.jsp now come from attribute on request object %> - <%@ include file="src/main/webapp/jsp/oncoprint/main.jsp" %> -
- - - <% if(showCancerTypesSummary) { %> - <%@ include file="src/main/webapp/jsp/pancancer_study_summary.jsp"%> - <%}%> - - <% if(showPlotsTab) { %> - <%@ include file="src/main/webapp/jsp/plots_tab.jsp" %> - <% } else { %> - <%@ include file="src/main/webapp/jsp/cross_cancer_plots_tab.jsp" %> - <% }%> - - <% if (showIGVtab) { %> - <%@ include file="src/main/webapp/jsp/igv.jsp" %> - <% } %> - - <% if (has_survival) { %> - <%@ include file="src/main/webapp/jsp/survival_tab.jsp" %> - <% } %> - - <% if (computeLogOddsRatio) { %> - <%@ include file="src/main/webapp/jsp/mutex_tab.jsp" %> - <% } %> - - <% if (mutationDetailLimitReached != null) { - out.println("
"); - out.println("

To retrieve mutation details, please specify " - + QueryBuilder.MUTATION_DETAIL_LIMIT + " or fewer genes.
"); - out.println("

"); - } else if (showMutTab) { %> - <%@ include file="src/main/webapp/jsp/mutation_details.jsp" %> - <% } %> - - <% if (includeNetworks) { %> - <%@ include file="src/main/webapp/jsp/networks.jsp" %> - <% } %> - - <% if (showCoexpTab) { %> - <%@ include file="src/main/webapp/jsp/co_expression.jsp" %> - <% } %> - - <% if ((has_mrna || has_copy_no || showMutTab) && !isVirtualStudy) { %> - <%@ include file="src/main/webapp/jsp/enrichments_tab.jsp" %> - <% } %> - <% if(showDownloadTab) { %> - <%@ include file="src/main/webapp/jsp/data_download.jsp" %> - <% } %> - -
- - -
- - - - - - - - -
- - - - - - - - - - - - - diff --git a/src/test/java/org/cbioportal/persistence/mybatis/MutationMyBatisRepositoryTest.java b/src/test/java/org/cbioportal/persistence/mybatis/MutationMyBatisRepositoryTest.java index 4919a9e4a8f..723f200c30f 100644 --- a/src/test/java/org/cbioportal/persistence/mybatis/MutationMyBatisRepositoryTest.java +++ b/src/test/java/org/cbioportal/persistence/mybatis/MutationMyBatisRepositoryTest.java @@ -1,14 +1,9 @@ package org.cbioportal.persistence.mybatis; -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; import org.cbioportal.model.AlleleSpecificCopyNumber; import org.cbioportal.model.Gene; import org.cbioportal.model.GeneFilterQuery; +import org.cbioportal.model.GenomicDataCountItem; import org.cbioportal.model.Mutation; import org.cbioportal.model.MutationCountByPosition; import org.cbioportal.model.meta.MutationMeta; @@ -25,7 +20,10 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = {MutationMyBatisRepository.class, MolecularProfileCaseIdentifierUtil.class, TestConfig.class}) @@ -104,7 +102,7 @@ public void init() { public void getMutationsInMolecularProfileBySampleListIdIdProjection() throws Exception { List result = mutationMyBatisRepository.getMutationsInMolecularProfileBySampleListId( - "study_tcga_pub_mutations", "study_tcga_pub_all", null, null, "ID", null, null, null, null); + "study_tcga_pub_mutations", "study_tcga_pub_all", null, false, "ID", null, null, null, null); Assert.assertEquals(8, result.size()); Mutation mutation = result.get(0); @@ -117,7 +115,7 @@ public void getMutationsInMolecularProfileBySampleListIdIdProjection() throws Ex public void getMutationsInMolecularProfileBySampleListIdSummaryProjection() throws Exception { List result = mutationMyBatisRepository.getMutationsInMolecularProfileBySampleListId( - "study_tcga_pub_mutations", "study_tcga_pub_all", null, null, "SUMMARY", null, null, null, null); + "study_tcga_pub_mutations", "study_tcga_pub_all", null, false, "SUMMARY", null, null, null, null); Assert.assertEquals(8, result.size()); @@ -162,7 +160,7 @@ public void getMutationsInMolecularProfileBySampleListIdAndEntrezGeneIdsSummaryP entrezGeneIds.add(208); List result = mutationMyBatisRepository.getMutationsInMolecularProfileBySampleListId( - "study_tcga_pub_mutations", "study_tcga_pub_all", entrezGeneIds, null, "SUMMARY", null, null, null, null); + "study_tcga_pub_mutations", "study_tcga_pub_all", entrezGeneIds, false, "SUMMARY", null, null, null, null); Assert.assertEquals(3, result.size()); Optional mutationOptional = @@ -203,7 +201,7 @@ public void getMutationsInMolecularProfileBySampleListIdAndEntrezGeneIdsSummaryP public void getMutationsInMolecularProfileBySampleListIdDetailedProjection() throws Exception { List result = mutationMyBatisRepository.getMutationsInMolecularProfileBySampleListId( - "study_tcga_pub_mutations", "study_tcga_pub_all", null, null, "DETAILED", null, null, null, null); + "study_tcga_pub_mutations", "study_tcga_pub_all", null, false, "DETAILED", null, null, null, null); Assert.assertEquals(8, result.size()); @@ -258,7 +256,7 @@ public void getMutationsInMolecularProfileBySampleListIdDetailedProjection() thr public void getMutationsInMolecularProfileBySampleListIdSummaryProjection1PageSize() throws Exception { List result = mutationMyBatisRepository.getMutationsInMolecularProfileBySampleListId( - "study_tcga_pub_mutations", "study_tcga_pub_all", null, null, "SUMMARY", 1, 0, null, null); + "study_tcga_pub_mutations", "study_tcga_pub_all", null, false, "SUMMARY", 1, 0, null, null); Assert.assertEquals(1, result.size()); } @@ -267,7 +265,7 @@ public void getMutationsInMolecularProfileBySampleListIdSummaryProjection1PageSi public void getMutationsInMolecularProfileBySampleListIdSummaryProjectionProteinChangeSort() throws Exception { List result = mutationMyBatisRepository.getMutationsInMolecularProfileBySampleListId( - "study_tcga_pub_mutations", "study_tcga_pub_all", null, null, "SUMMARY", null, null, "proteinChange", "ASC"); + "study_tcga_pub_mutations", "study_tcga_pub_all", null, false, "SUMMARY", null, null, "proteinChange", "ASC"); Assert.assertEquals(8, result.size()); Assert.assertEquals("C27_splice", result.get(0).getProteinChange()); @@ -539,7 +537,7 @@ public void fetchMutationsInMolecularProfile() throws Exception { sampleIds.add("TCGA-A1-A0SO-01"); List result = mutationMyBatisRepository.fetchMutationsInMolecularProfile("study_tcga_pub_mutations", - sampleIds, null, null, "SUMMARY", null, null, null, null); + sampleIds, null, false, "SUMMARY", null, null, null, null); Assert.assertEquals(3, result.size()); Assert.assertEquals("study_tcga_pub_mutations", result.get(0).getMolecularProfileId()); @@ -574,4 +572,18 @@ public void getMutationCountByPosition() throws Exception { Assert.assertEquals((Integer) 936, result.getProteinPosEnd()); Assert.assertEquals((Integer) 3, result.getCount()); } + + @Test + public void getMutationCountsByType() { + GenomicDataCountItem result = mutationMyBatisRepository.getMutationCountsByType( + Collections.singletonList("study_tcga_pub_mutations"), + sampleIds, + Collections.singletonList(207), + "mutations" + ); + + Assert.assertEquals("AKT1", result.getHugoGeneSymbol()); + Assert.assertEquals("mutations", result.getProfileType()); + Assert.assertEquals(2, result.getCounts().size()); + } } diff --git a/src/test/java/org/cbioportal/service/impl/MolecularProfileServiceImplTest.java b/src/test/java/org/cbioportal/service/impl/MolecularProfileServiceImplTest.java index 621e8a72f06..ab68f88124a 100644 --- a/src/test/java/org/cbioportal/service/impl/MolecularProfileServiceImplTest.java +++ b/src/test/java/org/cbioportal/service/impl/MolecularProfileServiceImplTest.java @@ -6,9 +6,10 @@ import org.cbioportal.service.StudyService; import org.cbioportal.service.exception.MolecularProfileNotFoundException; import org.cbioportal.service.exception.StudyNotFoundException; +import org.cbioportal.service.util.MolecularProfileUtil; import org.junit.Assert; -import org.junit.Test; import org.junit.Before; +import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; @@ -16,7 +17,10 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.test.util.ReflectionTestUtils; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; @RunWith(MockitoJUnitRunner.class) public class MolecularProfileServiceImplTest extends BaseServiceImplTest { @@ -28,6 +32,8 @@ public class MolecularProfileServiceImplTest extends BaseServiceImplTest { private MolecularProfileRepository molecularProfileRepository; @Mock private StudyService studyService; + @Mock + private MolecularProfileUtil molecularProfileUtil; @Before public void setup() { @@ -180,4 +186,38 @@ public void getMetaMolecularProfilesInStudies() throws Exception { Assert.assertEquals(expectedBaseMeta, result); } + + @Test + public void getMolecularProfilesReferredBy() throws Exception { + List expectedMolecularProfileList = new ArrayList<>(); + MolecularProfile molecularProfile = new MolecularProfile(); + expectedMolecularProfileList.add(molecularProfile); + + Mockito.when(molecularProfileRepository.getMolecularProfile(MOLECULAR_PROFILE_ID)) + .thenReturn(molecularProfile); + Mockito.when(molecularProfileRepository.getMolecularProfilesReferredBy(MOLECULAR_PROFILE_ID)) + .thenReturn(expectedMolecularProfileList); + + List result = molecularProfileService.getMolecularProfilesReferredBy( + MOLECULAR_PROFILE_ID); + + Assert.assertEquals(expectedMolecularProfileList, result); + } + + @Test + public void getMolecularProfilesReferringTo() throws Exception { + List expectedMolecularProfileList = new ArrayList<>(); + MolecularProfile molecularProfile = new MolecularProfile(); + expectedMolecularProfileList.add(molecularProfile); + + Mockito.when(molecularProfileRepository.getMolecularProfile(MOLECULAR_PROFILE_ID)) + .thenReturn(molecularProfile); + Mockito.when(molecularProfileRepository.getMolecularProfilesReferringTo(MOLECULAR_PROFILE_ID)) + .thenReturn(expectedMolecularProfileList); + + List result = molecularProfileService.getMolecularProfilesReferringTo( + MOLECULAR_PROFILE_ID); + + Assert.assertEquals(expectedMolecularProfileList, result); + } } diff --git a/src/test/java/org/cbioportal/service/impl/MutationServiceImplTest.java b/src/test/java/org/cbioportal/service/impl/MutationServiceImplTest.java index e8bc163e3ea..e89edc0627f 100644 --- a/src/test/java/org/cbioportal/service/impl/MutationServiceImplTest.java +++ b/src/test/java/org/cbioportal/service/impl/MutationServiceImplTest.java @@ -2,9 +2,12 @@ import org.cbioportal.model.Gene; import org.cbioportal.model.GeneFilterQuery; +import org.cbioportal.model.GenomicDataCount; +import org.cbioportal.model.GenomicDataCountItem; import org.cbioportal.model.MolecularProfile; import org.cbioportal.model.Mutation; import org.cbioportal.model.MutationCountByPosition; +import org.cbioportal.model.MutationEventType; import org.cbioportal.model.meta.MutationMeta; import org.cbioportal.persistence.MutationRepository; import org.cbioportal.service.MolecularProfileService; @@ -19,6 +22,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import static org.mockito.ArgumentMatchers.anyList; @@ -51,11 +55,11 @@ public void getMutationsInMolecularProfileBySampleListId() throws Exception { expectedMutationList.add(mutation); Mockito.when(mutationRepository.getMutationsInMolecularProfileBySampleListId(MOLECULAR_PROFILE_ID, - SAMPLE_LIST_ID, Arrays.asList(ENTREZ_GENE_ID_1), null, PROJECTION, PAGE_SIZE, PAGE_NUMBER, SORT, DIRECTION)) + SAMPLE_LIST_ID, Arrays.asList(ENTREZ_GENE_ID_1), false, PROJECTION, PAGE_SIZE, PAGE_NUMBER, SORT, DIRECTION)) .thenReturn(expectedMutationList); List result = mutationService.getMutationsInMolecularProfileBySampleListId(MOLECULAR_PROFILE_ID, - SAMPLE_LIST_ID, Arrays.asList(ENTREZ_GENE_ID_1), null, PROJECTION, PAGE_SIZE, PAGE_NUMBER, SORT, DIRECTION); + SAMPLE_LIST_ID, Arrays.asList(ENTREZ_GENE_ID_1), false, PROJECTION, PAGE_SIZE, PAGE_NUMBER, SORT, DIRECTION); Assert.assertEquals(expectedMutationList, result); Assert.assertEquals("19", result.get(0).getChr()); @@ -67,7 +71,7 @@ public void getMutationsInMolecularProfileBySampleListIdMolecularProfileNotFound Mockito.when(molecularProfileService.getMolecularProfile(MOLECULAR_PROFILE_ID)).thenThrow( new MolecularProfileNotFoundException(MOLECULAR_PROFILE_ID)); mutationService.getMutationsInMolecularProfileBySampleListId(MOLECULAR_PROFILE_ID, SAMPLE_LIST_ID, - Arrays.asList(ENTREZ_GENE_ID_1), null, PROJECTION, PAGE_SIZE, PAGE_NUMBER, SORT, DIRECTION); + Arrays.asList(ENTREZ_GENE_ID_1), false, PROJECTION, PAGE_SIZE, PAGE_NUMBER, SORT, DIRECTION); } @Test @@ -166,11 +170,11 @@ public void fetchMutationsInMolecularProfile() throws Exception { expectedMutationList.add(mutation); Mockito.when(mutationRepository.fetchMutationsInMolecularProfile(MOLECULAR_PROFILE_ID, - Arrays.asList(SAMPLE_ID1), Arrays.asList(ENTREZ_GENE_ID_1), null, PROJECTION, PAGE_SIZE, PAGE_NUMBER, SORT, + Arrays.asList(SAMPLE_ID1), Arrays.asList(ENTREZ_GENE_ID_1), false, PROJECTION, PAGE_SIZE, PAGE_NUMBER, SORT, DIRECTION)).thenReturn(expectedMutationList); List result = mutationService.fetchMutationsInMolecularProfile(MOLECULAR_PROFILE_ID, - Arrays.asList(SAMPLE_ID1), Arrays.asList(ENTREZ_GENE_ID_1), null, PROJECTION, PAGE_SIZE, PAGE_NUMBER, SORT, + Arrays.asList(SAMPLE_ID1), Arrays.asList(ENTREZ_GENE_ID_1), false, PROJECTION, PAGE_SIZE, PAGE_NUMBER, SORT, DIRECTION); Assert.assertEquals(expectedMutationList, result); @@ -183,7 +187,7 @@ public void fetchMutationsInMolecularProfileNotFound() throws Exception { Mockito.when(molecularProfileService.getMolecularProfile(MOLECULAR_PROFILE_ID)).thenThrow( new MolecularProfileNotFoundException(MOLECULAR_PROFILE_ID)); mutationService.fetchMutationsInMolecularProfile(MOLECULAR_PROFILE_ID, Arrays.asList(SAMPLE_ID1), - Arrays.asList(ENTREZ_GENE_ID_1), null, PROJECTION, PAGE_SIZE, PAGE_NUMBER, SORT, DIRECTION); + Arrays.asList(ENTREZ_GENE_ID_1), false, PROJECTION, PAGE_SIZE, PAGE_NUMBER, SORT, DIRECTION); } @Test @@ -224,4 +228,28 @@ public void fetchMutationCountsByPosition() throws Exception { Assert.assertEquals(1, result.size()); Assert.assertEquals(expectedMutationCountByPosition, result.get(0)); } + + @Test + public void getMutationCountsByType() { + GenomicDataCountItem expectedGenomicDataCountItem = new GenomicDataCountItem(); + expectedGenomicDataCountItem.setProfileType(PROFILE_TYPE_1); + expectedGenomicDataCountItem.setHugoGeneSymbol(HUGO_GENE_SYMBOL_1); + GenomicDataCount expectedGenomicDataCount = new GenomicDataCount(); + expectedGenomicDataCount.setLabel(MutationEventType.missense_mutation.getMutationType()); + expectedGenomicDataCount.setValue(MutationEventType.missense_mutation.getMutationType()); + expectedGenomicDataCount.setCount(2); + expectedGenomicDataCount.setUniqueCount(1); + expectedGenomicDataCountItem.setCounts(Collections.singletonList(expectedGenomicDataCount)); + + Mockito.when(mutationRepository.getMutationCountsByType( + Collections.singletonList(MOLECULAR_PROFILE_ID), Collections.singletonList(SAMPLE_ID1), + Collections.singletonList(ENTREZ_GENE_ID_1), PROFILE_TYPE_1)).thenReturn(expectedGenomicDataCountItem); + + GenomicDataCountItem result = mutationService.getMutationCountsByType( + Collections.singletonList(MOLECULAR_PROFILE_ID), Collections.singletonList(SAMPLE_ID1), + Collections.singletonList(ENTREZ_GENE_ID_1), PROFILE_TYPE_1); + + Assert.assertEquals(expectedGenomicDataCountItem, result); + Assert.assertEquals(1, result.getCounts().size()); + } } \ No newline at end of file diff --git a/src/test/java/org/cbioportal/service/impl/StudyViewServiceImplTest.java b/src/test/java/org/cbioportal/service/impl/StudyViewServiceImplTest.java index 801ab8afebf..e714ec3ea0d 100644 --- a/src/test/java/org/cbioportal/service/impl/StudyViewServiceImplTest.java +++ b/src/test/java/org/cbioportal/service/impl/StudyViewServiceImplTest.java @@ -1,9 +1,31 @@ package org.cbioportal.service.impl; import org.apache.commons.math3.util.Pair; -import org.cbioportal.model.*; +import org.cbioportal.model.AlterationCountByGene; +import org.cbioportal.model.AlterationFilter; +import org.cbioportal.model.CNA; +import org.cbioportal.model.CopyNumberCountByGene; +import org.cbioportal.model.Gene; +import org.cbioportal.model.GeneMolecularData; +import org.cbioportal.model.GenePanelData; +import org.cbioportal.model.GenericAssayData; +import org.cbioportal.model.GenericAssayDataCount; +import org.cbioportal.model.GenericAssayDataCountItem; +import org.cbioportal.model.GenomicDataCount; +import org.cbioportal.model.GenomicDataCountItem; +import org.cbioportal.model.MolecularProfile; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.model.MutationEventType; import org.cbioportal.model.util.Select; -import org.cbioportal.service.*; +import org.cbioportal.service.AlterationCountService; +import org.cbioportal.service.GenePanelService; +import org.cbioportal.service.GeneService; +import org.cbioportal.service.GenericAssayService; +import org.cbioportal.service.MolecularDataService; +import org.cbioportal.service.MolecularProfileService; +import org.cbioportal.service.MutationService; +import org.cbioportal.service.SignificantCopyNumberRegionService; +import org.cbioportal.service.SignificantlyMutatedGeneService; import org.cbioportal.service.util.MolecularProfileUtil; import org.junit.Assert; import org.junit.Test; @@ -13,14 +35,24 @@ import org.mockito.Mockito; import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.boot.test.mock.mockito.MockBean; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; -import static org.mockito.ArgumentMatchers.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.ArgumentMatchers.anyString; @RunWith(MockitoJUnitRunner.class) public class StudyViewServiceImplTest extends BaseServiceImplTest { - + + @Spy @InjectMocks private StudyViewServiceImpl studyViewService; @Mock @@ -28,7 +60,7 @@ public class StudyViewServiceImplTest extends BaseServiceImplTest { @Mock private GenePanelService genePanelService; @Spy - @InjectMocks + @MockBean private MolecularProfileUtil molecularProfileUtil; @Mock private AlterationCountService alterationCountService; @@ -42,6 +74,8 @@ public class StudyViewServiceImplTest extends BaseServiceImplTest { private MolecularDataService molecularDataService; @Mock private GeneService geneService; + @Mock + private MutationService mutationService; private AlterationFilter alterationFilter = new AlterationFilter(); @Test @@ -185,6 +219,122 @@ public void getMutationAlterationCountByGenes() throws Exception { Assert.assertEquals(1, result.size()); } + @Test + public void getMutationCountsByGeneSpecific() { + List studyIds = Arrays.asList(BaseServiceImplTest.STUDY_ID, BaseServiceImplTest.STUDY_ID); + List sampleIds = Arrays.asList(BaseServiceImplTest.SAMPLE_ID1, BaseServiceImplTest.SAMPLE_ID2); + + MolecularProfile molecularProfile = new MolecularProfile(); + molecularProfile.setCancerStudyIdentifier(BaseServiceImplTest.STUDY_ID); + List molecularProfileCaseIdentifiers = new ArrayList<>(); + MolecularProfileCaseIdentifier profileCaseIdentifier1 = new MolecularProfileCaseIdentifier(BaseServiceImplTest.SAMPLE_ID1, BaseServiceImplTest.MOLECULAR_PROFILE_ID); + molecularProfileCaseIdentifiers.add(profileCaseIdentifier1); + MolecularProfileCaseIdentifier profileCaseIdentifier2 = new MolecularProfileCaseIdentifier(BaseServiceImplTest.SAMPLE_ID2, BaseServiceImplTest.MOLECULAR_PROFILE_ID); + molecularProfileCaseIdentifiers.add(profileCaseIdentifier2); + Mockito.when(molecularProfileService.getMutationProfileCaseIdentifiers(studyIds, sampleIds)) + .thenReturn(molecularProfileCaseIdentifiers); + + List hugoGeneSymbols = new ArrayList<>(); + hugoGeneSymbols.add(BaseServiceImplTest.HUGO_GENE_SYMBOL_1); + List genes = new ArrayList<>(); + Gene gene = new Gene(); + gene.setEntrezGeneId(BaseServiceImplTest.ENTREZ_GENE_ID_1); + gene.setHugoGeneSymbol(BaseServiceImplTest.HUGO_GENE_SYMBOL_1); + gene.setGeneticEntityId(BaseServiceImplTest.GENETIC_ENTITY_ID_1); + genes.add(gene); + Mockito.when(geneService.fetchGenes(hugoGeneSymbols, "HUGO_GENE_SYMBOL", "SUMMARY")) + .thenReturn(genes); + + List entrezGeneIds = new ArrayList<>(); + entrezGeneIds.add(ENTREZ_GENE_ID_1); + List alterationCountByGenes = new ArrayList<>(); + AlterationCountByGene alterationCountByGene1 = new AlterationCountByGene(); + alterationCountByGene1.setEntrezGeneId(BaseServiceImplTest.ENTREZ_GENE_ID_1); + alterationCountByGene1.setHugoGeneSymbol(BaseServiceImplTest.HUGO_GENE_SYMBOL_1); + alterationCountByGene1.setNumberOfAlteredCases(2); + alterationCountByGene1.setTotalCount(2); + alterationCountByGene1.setNumberOfProfiledCases(2); + alterationCountByGenes.add(alterationCountByGene1); + + Mockito.when(alterationCountService.getSampleMutationGeneCounts(anyList(), + any(), + anyBoolean(), + anyBoolean(), + any())) + .thenReturn(new Pair<>(alterationCountByGenes, 2L)); + + List> genomicDataFilters = new ArrayList<>(); + Pair genomicDataFilter = new Pair<>(BaseServiceImplTest.HUGO_GENE_SYMBOL_1, BaseServiceImplTest.PROFILE_TYPE_1); + genomicDataFilters.add(genomicDataFilter); + + List result = studyViewService.getMutationCountsByGeneSpecific( + studyIds, sampleIds, genomicDataFilters, alterationFilter); + Assert.assertEquals(1, result.size()); + Assert.assertEquals(1, result.get(0).getCounts().size()); + } + + @Test + public void getMutationTypeCountsByGeneSpecific() { + List studyIds = Arrays.asList(BaseServiceImplTest.STUDY_ID, BaseServiceImplTest.STUDY_ID); + List sampleIds = Arrays.asList(BaseServiceImplTest.SAMPLE_ID1, BaseServiceImplTest.SAMPLE_ID2); + + List hugoGeneSymbols = new ArrayList<>(); + hugoGeneSymbols.add(BaseServiceImplTest.HUGO_GENE_SYMBOL_1); + List genes = new ArrayList<>(); + Gene gene = new Gene(); + gene.setEntrezGeneId(BaseServiceImplTest.ENTREZ_GENE_ID_1); + gene.setHugoGeneSymbol(BaseServiceImplTest.HUGO_GENE_SYMBOL_1); + gene.setGeneticEntityId(BaseServiceImplTest.GENETIC_ENTITY_ID_1); + genes.add(gene); + Mockito.when(geneService.fetchGenes(hugoGeneSymbols, "HUGO_GENE_SYMBOL", "SUMMARY")) + .thenReturn(genes); + + List molecularProfiles = new ArrayList<>(); + MolecularProfile molecularProfile = new MolecularProfile(); + molecularProfile.setCancerStudyIdentifier(BaseServiceImplTest.STUDY_ID); + molecularProfile.setStableId(BaseServiceImplTest.STABLE_ID_1); + molecularProfiles.add(molecularProfile); + Mockito.when(molecularProfileService.getMolecularProfilesInStudies(studyIds, "SUMMARY")) + .thenReturn(molecularProfiles); + + Map> molecularProfileMap = new HashMap<>(); + molecularProfileMap.put(BaseServiceImplTest.PROFILE_TYPE_1, molecularProfiles); + Mockito.when(molecularProfileUtil.categorizeMolecularProfilesByStableIdSuffixes(molecularProfiles)) + .thenReturn(molecularProfileMap); + + GenomicDataCountItem genomicDataCountItem = new GenomicDataCountItem(); + genomicDataCountItem.setHugoGeneSymbol(BaseServiceImplTest.HUGO_GENE_SYMBOL_1); + genomicDataCountItem.setProfileType(BaseServiceImplTest.PROFILE_TYPE_1); + List genomicDataCounts = new ArrayList<>(); + GenomicDataCount genomicDataCount1 = new GenomicDataCount(); + genomicDataCount1.setLabel(MutationEventType.missense_mutation.getMutationType()); + genomicDataCount1.setValue(MutationEventType.missense_mutation.getMutationType()); + genomicDataCount1.setCount(2); + genomicDataCounts.add(genomicDataCount1); + GenomicDataCount genomicDataCount2 = new GenomicDataCount(); + genomicDataCount2.setLabel(MutationEventType.splice_site_indel.getMutationType()); + genomicDataCount2.setValue(MutationEventType.splice_site_indel.getMutationType()); + genomicDataCount2.setCount(2); + genomicDataCounts.add(genomicDataCount2); + genomicDataCountItem.setCounts(genomicDataCounts); + + Mockito.when(mutationService.getMutationCountsByType( + anyList(), anyList(), anyList(), anyString() + )).thenReturn(genomicDataCountItem); + + List> genomicDataFilters = new ArrayList<>(); + Pair genomicDataFilter = new Pair<>(BaseServiceImplTest.HUGO_GENE_SYMBOL_1, BaseServiceImplTest.PROFILE_TYPE_1); + genomicDataFilters.add(genomicDataFilter); + + List result = studyViewService.getMutationTypeCountsByGeneSpecific( + studyIds, sampleIds, genomicDataFilters); + Assert.assertEquals(1, result.size()); + Assert.assertEquals(BaseServiceImplTest.HUGO_GENE_SYMBOL_1, result.get(0).getHugoGeneSymbol()); + Assert.assertEquals(BaseServiceImplTest.PROFILE_TYPE_1, result.get(0).getProfileType()); + Assert.assertEquals(2, result.get(0).getCounts().get(0).getCount().intValue()); + Assert.assertEquals(2, result.get(0).getCounts().get(1).getCount().intValue()); + } + @Test public void getStructuralVariantAlterationCountByGenes() throws Exception { diff --git a/src/test/java/org/cbioportal/service/impl/UuidDataAccessTokenServiceImplTestConfiguration.java b/src/test/java/org/cbioportal/service/impl/UuidDataAccessTokenServiceImplTestConfiguration.java index fb7323c2580..d83ff6994fe 100644 --- a/src/test/java/org/cbioportal/service/impl/UuidDataAccessTokenServiceImplTestConfiguration.java +++ b/src/test/java/org/cbioportal/service/impl/UuidDataAccessTokenServiceImplTestConfiguration.java @@ -50,31 +50,17 @@ //TODO package org.cbioportal.security.spring.authentication.token; import java.util.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.TestPropertySource; + +import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; import org.mockito.ArgumentMatchers; import org.mockito.Mockito; import org.mockito.stubbing.Answer; import org.mockito.invocation.InvocationOnMock; -import org.mockito.junit.MockitoJUnitRunner; import org.cbioportal.model.DataAccessToken; import org.cbioportal.persistence.DataAccessTokenRepository; -import org.cbioportal.service.exception.TokenNotFoundException; -import org.cbioportal.service.impl.UuidDataAccessTokenServiceImpl; -@Configuration +@TestConfiguration public class UuidDataAccessTokenServiceImplTestConfiguration { public static String MOCK_USERNAME = "MOCK_USER"; diff --git a/src/test/java/org/cbioportal/service/util/JwtUtilsTestConfiguration.java b/src/test/java/org/cbioportal/service/util/JwtUtilsTestConfiguration.java index 1e25815ee63..5322922a2d6 100644 --- a/src/test/java/org/cbioportal/service/util/JwtUtilsTestConfiguration.java +++ b/src/test/java/org/cbioportal/service/util/JwtUtilsTestConfiguration.java @@ -49,10 +49,10 @@ package org.cbioportal.service.util; //TODO package org.cbioportal.security.spring.authentication.token; -import org.springframework.context.annotation.Configuration; +import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; -@Configuration +@TestConfiguration public class JwtUtilsTestConfiguration { @Bean diff --git a/src/test/java/org/cbioportal/service/util/MolecularProfileUtilTest.java b/src/test/java/org/cbioportal/service/util/MolecularProfileUtilTest.java index ffa0d9c4eac..078acc83e06 100644 --- a/src/test/java/org/cbioportal/service/util/MolecularProfileUtilTest.java +++ b/src/test/java/org/cbioportal/service/util/MolecularProfileUtilTest.java @@ -13,12 +13,84 @@ import java.util.Arrays; import java.util.List; import java.util.Optional; +import java.util.function.Predicate; @RunWith(MockitoJUnitRunner.class) public class MolecularProfileUtilTest { @InjectMocks private MolecularProfileUtil molecularProfileUtil; + @Test + public void getFirstFilteredMolecularProfileCaseIdentifiers() { + + MolecularProfile mutationMolecularProfile = new MolecularProfile(); + mutationMolecularProfile.setCancerStudyIdentifier(BaseServiceImplTest.STUDY_ID); + mutationMolecularProfile.setStableId(BaseServiceImplTest.STUDY_ID + "_mutations"); + mutationMolecularProfile.setMolecularAlterationType(MolecularProfile.MolecularAlterationType.MUTATION_EXTENDED); + mutationMolecularProfile.setDatatype("MAF"); + + MolecularProfile structuralVariantMolecularProfile = new MolecularProfile(); + structuralVariantMolecularProfile.setCancerStudyIdentifier(BaseServiceImplTest.STUDY_ID); + structuralVariantMolecularProfile.setStableId(BaseServiceImplTest.STUDY_ID + "_structural_variants"); + structuralVariantMolecularProfile.setMolecularAlterationType(MolecularProfile.MolecularAlterationType.STRUCTURAL_VARIANT); + structuralVariantMolecularProfile.setDatatype("SV"); + + MolecularProfile discreteCNAMolecularProfile = new MolecularProfile(); + discreteCNAMolecularProfile.setCancerStudyIdentifier(BaseServiceImplTest.STUDY_ID); + discreteCNAMolecularProfile.setStableId(BaseServiceImplTest.STUDY_ID + "_gistic"); + discreteCNAMolecularProfile.setMolecularAlterationType(MolecularProfile.MolecularAlterationType.COPY_NUMBER_ALTERATION); + discreteCNAMolecularProfile.setDatatype("DISCRETE"); + + MolecularProfile linearCNAMolecularProfile = new MolecularProfile(); + linearCNAMolecularProfile.setCancerStudyIdentifier(BaseServiceImplTest.STUDY_ID); + linearCNAMolecularProfile.setStableId(BaseServiceImplTest.STUDY_ID + "_linear_CNA"); + linearCNAMolecularProfile.setMolecularAlterationType(MolecularProfile.MolecularAlterationType.COPY_NUMBER_ALTERATION); + linearCNAMolecularProfile.setDatatype("CONTINUOUS"); + + MolecularProfile continuousMRNAMolecularProfile = new MolecularProfile(); + continuousMRNAMolecularProfile.setCancerStudyIdentifier(BaseServiceImplTest.STUDY_ID); + continuousMRNAMolecularProfile.setStableId(BaseServiceImplTest.STUDY_ID + "_rna_seq_mrna"); + continuousMRNAMolecularProfile.setMolecularAlterationType(MolecularProfile.MolecularAlterationType.MRNA_EXPRESSION); + continuousMRNAMolecularProfile.setDatatype("CONTINUOUS"); + + MolecularProfile discreteMRNAMolecularProfile = new MolecularProfile(); + discreteMRNAMolecularProfile.setCancerStudyIdentifier(BaseServiceImplTest.STUDY_ID); + discreteMRNAMolecularProfile.setStableId(BaseServiceImplTest.STUDY_ID + "_rna_seq_mrna_median_Zscores"); + discreteMRNAMolecularProfile.setMolecularAlterationType(MolecularProfile.MolecularAlterationType.MRNA_EXPRESSION); + discreteMRNAMolecularProfile.setDatatype("DISCRETE"); + + List studyIds = Arrays.asList(BaseServiceImplTest.STUDY_ID, BaseServiceImplTest.STUDY_ID, BaseServiceImplTest.STUDY_ID); + List sampleIds = Arrays.asList(BaseServiceImplTest.SAMPLE_ID1, BaseServiceImplTest.SAMPLE_ID2, BaseServiceImplTest.SAMPLE_ID3); + + + List result = molecularProfileUtil.getFirstFilteredMolecularProfileCaseIdentifiers(new ArrayList<>(), studyIds, sampleIds, Optional.empty()); + // no molecular profiles + Assert.assertEquals(0, result.size()); + + List allMolecularProfiles = Arrays.asList(mutationMolecularProfile, + structuralVariantMolecularProfile, + discreteCNAMolecularProfile, + linearCNAMolecularProfile, + continuousMRNAMolecularProfile, + discreteMRNAMolecularProfile); + result = molecularProfileUtil.getFirstFilteredMolecularProfileCaseIdentifiers(allMolecularProfiles, studyIds, sampleIds, Optional.empty()); + // all molecular profiles + // return would 3(6 profiles X 3 samples) + Assert.assertEquals("all profiles", 3, result.size()); + + // filtered mutation profile case identifiers + result = molecularProfileUtil.getFirstFilteredMolecularProfileCaseIdentifiers(allMolecularProfiles, studyIds, sampleIds, Optional.of(molecularProfileUtil.isMutationProfile)); + Assert.assertEquals("mutation profile case identifiers", 3, result.size()); + + // filtered discrete CNA profile case identifiers + result = molecularProfileUtil.getFirstFilteredMolecularProfileCaseIdentifiers(allMolecularProfiles, studyIds, sampleIds, Optional.of(molecularProfileUtil.isDiscreteCNAMolecularProfile)); + Assert.assertEquals("discrete CNA profile case identifiers", 3, result.size()); + + // filtered structural variant profile case identifiers + result = molecularProfileUtil.getFirstFilteredMolecularProfileCaseIdentifiers(allMolecularProfiles, studyIds, sampleIds, Optional.of(molecularProfileUtil.isStructuralVariantMolecularProfile)); + Assert.assertEquals("structural variant profile case identifiers", 3, result.size()); + } + @Test public void getFilteredMolecularProfileCaseIdentifiers() { @@ -77,17 +149,22 @@ public void getFilteredMolecularProfileCaseIdentifiers() { // return would 18(6 profiles X 3 samples) instead of 24(8 profiles X 3 samples) Assert.assertEquals("all profiles", 18, result.size()); - //filtered mutation profile case identifiers + // filtered mutation profile case identifiers result = molecularProfileUtil.getFilteredMolecularProfileCaseIdentifiers(allMolecularProfiles, studyIds, sampleIds, Optional.of(molecularProfileUtil.isMutationProfile)); Assert.assertEquals("mutation profile case identifiers", 3, result.size()); - //filtered discrete CNA profile case identifiers + // filtered discrete CNA profile case identifiers result = molecularProfileUtil.getFilteredMolecularProfileCaseIdentifiers(allMolecularProfiles, studyIds, sampleIds, Optional.of(molecularProfileUtil.isDiscreteCNAMolecularProfile)); Assert.assertEquals("discrete CNA profile case identifiers", 3, result.size()); - //filtered structural variant profile case identifiers + // filtered structural variant profile case identifiers result = molecularProfileUtil.getFilteredMolecularProfileCaseIdentifiers(allMolecularProfiles, studyIds, sampleIds, Optional.of(molecularProfileUtil.isStructuralVariantMolecularProfile)); Assert.assertEquals("structural variant profile case identifiers", 3, result.size()); + // filtered MRNA expression profile case identifiers (multiple molecular profiles) + Predicate isMRNAProfile = + m -> m.getMolecularAlterationType().equals(MolecularProfile.MolecularAlterationType.MRNA_EXPRESSION); + result = molecularProfileUtil.getFilteredMolecularProfileCaseIdentifiers(allMolecularProfiles, studyIds, sampleIds, Optional.of(isMRNAProfile)); + Assert.assertEquals("structural variant profile case identifiers", 6, result.size()); } } diff --git a/src/test/java/org/cbioportal/test/integration/MysqlInitializer.java b/src/test/java/org/cbioportal/test/integration/MysqlInitializer.java index 716df444763..a4b60e3c741 100644 --- a/src/test/java/org/cbioportal/test/integration/MysqlInitializer.java +++ b/src/test/java/org/cbioportal/test/integration/MysqlInitializer.java @@ -3,14 +3,15 @@ import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; +import org.testcontainers.containers.MySQLContainer; public abstract class MysqlInitializer implements ApplicationContextInitializer { public void initializeImpl(ConfigurableApplicationContext configurableApplicationContext, - SharedMysqlContainer mysqlContainer) { + MySQLContainer mysqlContainer) { TestPropertyValues values = TestPropertyValues.of( - String.format("spring.datasource.url=%s", mysqlContainer.getJdbcUrl()), + String.format("spring.datasource.url=%s?useSSL=false&allowPublicKeyRetrieval=true", mysqlContainer.getJdbcUrl()), String.format("spring.datasource.username=%s", mysqlContainer.getUsername()), String.format("spring.datasource.password=%s", mysqlContainer.getPassword()) ); diff --git a/src/test/java/org/cbioportal/test/integration/OAuth2KeycloakInitializer.java b/src/test/java/org/cbioportal/test/integration/OAuth2KeycloakInitializer.java index 600f0327756..ea8b64b507f 100644 --- a/src/test/java/org/cbioportal/test/integration/OAuth2KeycloakInitializer.java +++ b/src/test/java/org/cbioportal/test/integration/OAuth2KeycloakInitializer.java @@ -18,35 +18,21 @@ public void initializeImpl(ConfigurableApplicationContext configurableApplicatio try { String keycloakUrlForCBioportal = keycloakContainer.getAuthServerUrl(); - String keycloakUrlForBrowser = "http://keycloak:8080/auth"; + String keycloakUrlForBrowser = String.format("http://localhost:%s", keycloakContainer.getHttpPort()); TestPropertyValues values = TestPropertyValues.of( // These urls are from the perspective of cBioPortal application (port on host system). - String.format( - "spring.security.oauth2.client.provider.cbio-idp.issuer=%s/realms/cbio", - keycloakUrlForCBioportal), - String.format( - "spring.security.oauth2.client.provider.cbio-idp.token-uri=%s/realms/cbio/protocol/openid-connect/token", - keycloakUrlForCBioportal), - String.format( - "spring.security.oauth2.client.provider.cbio-idp.user-info-uri=%s/realms/cbio/protocol/openid-connect/userinfo", - keycloakUrlForCBioportal), - String.format( - "spring.security.oauth2.client.provider.cbio-idp.jwk-set-uri=%s/realms/cbio/protocol/openid-connect/certs", - keycloakUrlForCBioportal), + String.format( "dat.oauth2.accessTokenUri=%s/realms/cbio/protocol/openid-connect/token", - keycloakUrlForCBioportal), + keycloakUrlForBrowser), String.format("dat.oauth2.jwkUrl=%s/realms/cbio/protocol/openid-connect/certs", - keycloakUrlForCBioportal), - - // This url is from the perspective of the browser. - String.format( - "spring.security.oauth2.client.provider.cbio-idp.authorization-uri=%s/realms/cbio/protocol/openid-connect/auth", keycloakUrlForBrowser), + + // This url is from the perspective of the browser. String.format( - "spring.security.oauth2.client.provider.cbio-idp.logout-uri=%s/realms/cbio/protocol/openid-connect/logout", + "spring.security.oauth2.client.provider.keycloak.issuer-uri=%s/realms/cbio", keycloakUrlForBrowser), String.format( "dat.oauth2.userAuthorizationUri=%s/realms/cbio/protocol/openid-connect/auth", diff --git a/src/test/java/org/cbioportal/test/integration/OAuth2ResourceServerKeycloakInitializer.java b/src/test/java/org/cbioportal/test/integration/OAuth2ResourceServerKeycloakInitializer.java new file mode 100644 index 00000000000..85191c99efd --- /dev/null +++ b/src/test/java/org/cbioportal/test/integration/OAuth2ResourceServerKeycloakInitializer.java @@ -0,0 +1,43 @@ +package org.cbioportal.test.integration; + +import dasniko.testcontainers.keycloak.KeycloakContainer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; + +public abstract class OAuth2ResourceServerKeycloakInitializer implements + ApplicationContextInitializer { + + private static final Logger log = LoggerFactory.getLogger(OAuth2KeycloakInitializer.class); + + public void initializeImpl(ConfigurableApplicationContext configurableApplicationContext, + KeycloakContainer keycloakContainer) { + String keycloakUrlForBrowser = keycloakContainer.getAuthServerUrl(); + + try { + TestPropertyValues values = TestPropertyValues.of( + // These urls are from the perspective of cBioPortal application (port on host system) + String.format( + "spring.security.saml2.relyingparty.registration.keycloak.assertingparty.metadata-uri=%s/realms/cbio/protocol/saml/descriptor", + keycloakUrlForBrowser), + + String.format("dat.oauth2.jwkUrl=%s/realms/cbio/protocol/openid-connect/certs", + keycloakUrlForBrowser), + + // This url is from the perspective of the browser + // Should match the id in the generated idp metadata xml (samlIdpMetadata) + String.format("spring.security.saml2.relyingparty.registration.keycloak.entity-id=cbioportal", + keycloakUrlForBrowser), + + String.format("dat.oauth2.issuer=%s/realms/cbio", keycloakUrlForBrowser) + ); + values.applyTo(configurableApplicationContext); + + } catch (Exception e) { + log.error("Error initializing keycloak container" + e.getMessage()); + } + } + +} diff --git a/src/test/java/org/cbioportal/test/integration/SamlKeycloakInitializer.java b/src/test/java/org/cbioportal/test/integration/SamlKeycloakInitializer.java index fe813a548a3..58cc09733f4 100644 --- a/src/test/java/org/cbioportal/test/integration/SamlKeycloakInitializer.java +++ b/src/test/java/org/cbioportal/test/integration/SamlKeycloakInitializer.java @@ -1,10 +1,6 @@ package org.cbioportal.test.integration; import dasniko.testcontainers.keycloak.KeycloakContainer; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.test.util.TestPropertyValues; @@ -22,28 +18,13 @@ public void initializeImpl(ConfigurableApplicationContext configurableApplicatio try { String keycloakUrlForCBioportal = keycloakContainer.getAuthServerUrl(); - String keycloakUrlForBrowser = "http://keycloak:8080/auth"; TestPropertyValues values = TestPropertyValues.of( - // Should match the id in the generated idp metadata xml (samlIdpMetadata) - String.format("spring.security.saml2.relyingparty.registration.cbio-idp.identityprovider.entity-id=%s/realms/cbio", - keycloakUrlForBrowser), // These urls are from the perspective of cBioPortal application (port on host system) String.format( - "spring.security.saml2.relyingparty.registration.cbio-idp.identityprovider.metadata-uri=%s/realms/cbio/protocol/saml/descriptor", - keycloakUrlForCBioportal), - String.format( - "dat.oauth2.accessTokenUri=%s/realms/cbio/protocol/openid-connect/token", - keycloakUrlForCBioportal), - String.format("dat.oauth2.jwkUrl=%s/realms/cbio/protocol/openid-connect/certs", - keycloakUrlForCBioportal), - - // This url is from the perspective of the browser - String.format( - "dat.oauth2.userAuthorizationUri=%s/realms/cbio/protocol/openid-connect/auth", - keycloakUrlForBrowser), - String.format("dat.oauth2.issuer=%s/realms/cbio", keycloakUrlForBrowser) + "spring.security.saml2.relyingparty.registration.keycloak.assertingparty.metadata-uri=%s/realms/cbio/protocol/saml/descriptor", + keycloakUrlForCBioportal) ); values.applyTo(configurableApplicationContext); diff --git a/src/test/java/org/cbioportal/test/integration/SharedChromeContainer.java b/src/test/java/org/cbioportal/test/integration/SharedChromeContainer.java deleted file mode 100644 index 3e57f5e01bf..00000000000 --- a/src/test/java/org/cbioportal/test/integration/SharedChromeContainer.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.cbioportal.test.integration; - -import static org.testcontainers.containers.BrowserWebDriverContainer.VncRecordingMode.RECORD_ALL; - - -import java.io.File; -import java.util.HashMap; -import java.util.Map; -import org.openqa.selenium.chrome.ChromeOptions; -import org.testcontainers.containers.BrowserWebDriverContainer; - -public class SharedChromeContainer extends BrowserWebDriverContainer { - - public final static String DOWNLOAD_FOLDER = "/tmp/browser_downloads"; - - private static BrowserWebDriverContainer container; - - private SharedChromeContainer() { - super(); - } - - // For test development a VNC viewer can be connected to the selenium container. - // Make sure to connect to exposed port on host system connected to internal - // port 5900 of the browser container. The password is 'secret'. - - public static BrowserWebDriverContainer getInstance() { - if (container == null) { - - ChromeOptions options = new ChromeOptions(); - Map prefs = new HashMap(); - prefs.put("download.default_directory", DOWNLOAD_FOLDER); - prefs.put("profile.default_content_settings.popups", 0); - prefs.put("download.prompt_for_download", "false"); - prefs.put("download.directory_upgrade", "true"); - options.setExperimentalOption("prefs", prefs); - - container = new BrowserWebDriverContainer<>() - // activate this to record movies of the tests (greate for debugging) - .withRecordingMode(RECORD_ALL, new File("/home/pnp300")) - .withNetwork(SharedKeycloakContainer.keycloakNetwork) - .withAccessToHost(true) - .withCapabilities(options); - } - return container; - } - -} diff --git a/src/test/java/org/cbioportal/test/integration/SharedKeycloakContainer.java b/src/test/java/org/cbioportal/test/integration/SharedKeycloakContainer.java deleted file mode 100644 index e69d81718c2..00000000000 --- a/src/test/java/org/cbioportal/test/integration/SharedKeycloakContainer.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.cbioportal.test.integration; - -import dasniko.testcontainers.keycloak.KeycloakContainer; -import org.testcontainers.containers.Network; - -public class SharedKeycloakContainer extends KeycloakContainer { - - private static final String IMAGE_VERSION = "jboss/keycloak:15.0.2"; - private static String kcAdminName = "admin"; - private static String kcAdminPassword = "admin"; - public static final Network keycloakNetwork = Network.newNetwork(); - private static KeycloakContainer container; - - private SharedKeycloakContainer() { - super(IMAGE_VERSION); - } - - public static KeycloakContainer getInstance() { - if (container == null) { - container = new KeycloakContainer() - .withRealmImportFile("security/keycloak-configuration-generated.json") - .withAdminUsername(kcAdminName) - .withAdminPassword(kcAdminPassword) - .withNetwork(keycloakNetwork) - .withNetworkAliases("keycloak") - // Needed because cBioPortal and Chrome use differnt urls to Keycloak container - // Causes mismatch of 'issuer' field in JWT. - // See: https://stackoverflow.com/a/65848717/11651683 - .withEnv("KEYCLOAK_FRONTEND_URL", "http://keycloak:8080/auth"); - } - return container; - } - -} diff --git a/src/test/java/org/cbioportal/test/integration/SharedMysqlContainer.java b/src/test/java/org/cbioportal/test/integration/SharedMysqlContainer.java deleted file mode 100644 index 78ad92024bd..00000000000 --- a/src/test/java/org/cbioportal/test/integration/SharedMysqlContainer.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.cbioportal.test.integration; - -import java.io.File; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.time.Duration; -import org.testcontainers.containers.BindMode; -import org.testcontainers.containers.MySQLContainer; - -public class SharedMysqlContainer extends MySQLContainer { - - private static final String IMAGE_VERSION = "mysql:5.7"; - private static SharedMysqlContainer container; - - private SharedMysqlContainer() { - super(IMAGE_VERSION); - } - - public static SharedMysqlContainer getInstance() { - if (container == null) { - container = new SharedMysqlContainer() - .withClasspathResourceMapping("cgds.sql", "/docker-entrypoint-initdb.d/a_schema.sql", BindMode.READ_ONLY) - .withClasspathResourceMapping("seed_mini.sql", "/docker-entrypoint-initdb.d/b_seed.sql", BindMode.READ_ONLY) - .withStartupTimeout(Duration.ofMinutes(10)); - } - return container; - } - - /** - * @param path path to file or directory from the root of the maven project - * @return Absolute path to file - */ - private static Path absolutePath(String path) { - return Paths.get(new File("../" + path).getAbsolutePath()); - } -} diff --git a/src/test/java/org/cbioportal/test/integration/security/ContainerConfig.java b/src/test/java/org/cbioportal/test/integration/security/ContainerConfig.java new file mode 100644 index 00000000000..b74ff9c542d --- /dev/null +++ b/src/test/java/org/cbioportal/test/integration/security/ContainerConfig.java @@ -0,0 +1,156 @@ +package org.cbioportal.test.integration.security; + +import dasniko.testcontainers.keycloak.KeycloakContainer; +import org.cbioportal.test.integration.MysqlInitializer; +import org.cbioportal.test.integration.OAuth2KeycloakInitializer; +import org.cbioportal.test.integration.OAuth2ResourceServerKeycloakInitializer; +import org.cbioportal.test.integration.SamlKeycloakInitializer; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; +import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.boot.web.context.WebServerInitializedEvent; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ApplicationListener; +import org.springframework.context.ConfigurableApplicationContext; +import org.testcontainers.Testcontainers; +import org.testcontainers.containers.BindMode; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.MySQLContainer; +import org.testcontainers.containers.Network; +import org.testcontainers.shaded.com.google.common.collect.ImmutableList; +import org.testcontainers.utility.DockerImageName; + +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; + +public class ContainerConfig { + + public final static int CBIO_PORT = 8080; + public final static int SESSION_SERVICE_PORT = 5000; + public final static int MONGO_PORT = 27017; + + public final static String MONGO_NETWORK = "mongo-network"; + public final static int MOCKSERVER_PORT = 8085; + public final static String DOWNLOAD_FOLDER = "/tmp/browser_downloads"; + + private static final String SESSION_IMAGE_VERSION = "docker.io/cbioportal/session-service:0.6.1"; + private static final String MONGO_IMAGE_VERSION = "docker.io/mongo:3.7.9"; + private static final String KEYCLOAK_IMAGE_VERSION = "quay.io/keycloak/keycloak:22.0.5"; + private static final String MYSQL_IMAGE_VERSION = "mysql:5.7"; + private static final String MOCKSERVER_IMAGE_VERSION = "docker.io/mockserver/mockserver:5.15.0"; + + static final MySQLContainer mysqlContainer; + static final GenericContainer mockServerContainer; + static final KeycloakContainer keycloakContainer; + static final ChromeDriver chromeDriver; + + static final GenericContainer sessionServiceContainer; + static final GenericContainer mongoContainer; + + static { + + Network mongoNetwork = Network.newNetwork(); + mongoContainer = new GenericContainer(DockerImageName.parse(MONGO_IMAGE_VERSION)) + .withNetwork(mongoNetwork) + .withNetworkAliases(MONGO_NETWORK) + .withAccessToHost(true) + .withEnv("MONGO_INITDB_DATABASE", "session_service"); + + String mongoConnectionString = String.format("-Dspring.data.mongodb.uri=mongodb://%s:%s/session-service",MONGO_NETWORK, MONGO_PORT); + sessionServiceContainer = new GenericContainer(DockerImageName.parse(SESSION_IMAGE_VERSION)) + .withNetwork(mongoNetwork) + .withAccessToHost(true) + .withEnv("SERVER_PORT", "5000") + .withEnv("JAVA_OPTS", mongoConnectionString); + sessionServiceContainer.setPortBindings(ImmutableList.of(String.format("%s:5000", SESSION_SERVICE_PORT))); + + keycloakContainer = new KeycloakContainer(KEYCLOAK_IMAGE_VERSION) + .withRealmImportFile("security/keycloak-configuration-generated.json") + .withAdminUsername("admin") + .withAdminPassword("admin") + .withEnv("KC_HOSTNAME", "localhost") + .withEnv("KC_HOSTNAME_ADMIN", "localhost"); + + mockServerContainer = new GenericContainer(MOCKSERVER_IMAGE_VERSION) + .withExposedPorts(1080); + mockServerContainer.setPortBindings(ImmutableList.of(String.format("%s:1080", MOCKSERVER_PORT))); + + mysqlContainer = (MySQLContainer) new MySQLContainer(MYSQL_IMAGE_VERSION) + .withClasspathResourceMapping("cgds.sql", "/docker-entrypoint-initdb.d/a_schema.sql", BindMode.READ_ONLY) + .withClasspathResourceMapping("seed_mini.sql", "/docker-entrypoint-initdb.d/b_seed.sql", BindMode.READ_ONLY) + .withStartupTimeout(Duration.ofMinutes(10)); + + ChromeOptions options = new ChromeOptions(); + options.addArguments("--no-sandbox"); + options.addArguments("--disable-dev-shm-usage"); + options.addArguments("--headless"); + Map prefs = new HashMap<>(); + prefs.put("download.default_directory", DOWNLOAD_FOLDER); + prefs.put("profile.default_content_settings.popups", 0); + prefs.put("download.prompt_for_download", "false"); + prefs.put("download.directory_upgrade", "true"); + options.setExperimentalOption("prefs", prefs); + chromeDriver = new ChromeDriver(options); + + mongoContainer.start(); + sessionServiceContainer.start(); + mysqlContainer.start(); + mockServerContainer.start(); + keycloakContainer.start(); + } + + // Update application properties with connection info on Keycloak container + public static class MySamlKeycloakInitializer extends SamlKeycloakInitializer { + @Override + public void initialize( + ConfigurableApplicationContext configurableApplicationContext) { + super.initializeImpl(configurableApplicationContext, keycloakContainer); + } + } + + // Update application properties with connection info on Keycloak container + public static class MyOAuth2KeycloakInitializer extends OAuth2KeycloakInitializer { + @Override + public void initialize( + ConfigurableApplicationContext configurableApplicationContext) { + super.initializeImpl(configurableApplicationContext, keycloakContainer); + } + } + + // Update application properties with connection info on Mysql container + public static class MyMysqlInitializer extends MysqlInitializer { + @Override + public void initialize( + ConfigurableApplicationContext configurableApplicationContext) { + super.initializeImpl(configurableApplicationContext, mysqlContainer); + } + } + + public static class MyOAuth2ResourceServerKeycloakInitializer extends OAuth2ResourceServerKeycloakInitializer { + @Override + public void initialize( + ConfigurableApplicationContext configurableApplicationContext) { + super.initializeImpl(configurableApplicationContext, keycloakContainer); + } + } + + // Expose the ports for the cBioPortal Spring application and keycloak inside + // the Chrome container. Each address is available on http://host.testcontainers.internal: + // in the browser container. + public static class PortInitializer implements + ApplicationContextInitializer { + @Override + public void initialize(ConfigurableApplicationContext applicationContext) { + TestPropertyValues values = TestPropertyValues.of( + "server.port=" + CBIO_PORT + ); + values.applyTo(applicationContext); + applicationContext.addApplicationListener( + (ApplicationListener) event -> { + Testcontainers.exposeHostPorts(CBIO_PORT, MONGO_PORT); + }); + } + } + +} \ No newline at end of file diff --git a/src/test/java/org/cbioportal/test/integration/security/OAuth2AuthIntegrationTest.java b/src/test/java/org/cbioportal/test/integration/security/OAuth2AuthIntegrationTest.java index 1fd90a7ebbc..1b580f2a2eb 100644 --- a/src/test/java/org/cbioportal/test/integration/security/OAuth2AuthIntegrationTest.java +++ b/src/test/java/org/cbioportal/test/integration/security/OAuth2AuthIntegrationTest.java @@ -1,44 +1,18 @@ package org.cbioportal.test.integration.security; -import static org.cbioportal.test.integration.security.OAuth2AuthIntegrationTest.*; -import static org.testcontainers.shaded.org.awaitility.Awaitility.await; - - -import dasniko.testcontainers.keycloak.KeycloakContainer; -import java.io.IOException; -import java.time.Duration; -import java.util.concurrent.Callable; -import javax.annotation.Nonnull; import org.cbioportal.PortalApplication; -import org.cbioportal.test.integration.MysqlInitializer; -import org.cbioportal.test.integration.OAuth2KeycloakInitializer; -import org.cbioportal.test.integration.SharedChromeContainer; -import org.cbioportal.test.integration.SharedKeycloakContainer; -import org.cbioportal.test.integration.SharedMysqlContainer; -import org.junit.ClassRule; -import org.junit.Ignore; +import org.cbioportal.test.integration.security.util.Util; import org.junit.Test; -import org.junit.jupiter.api.Assertions; import org.junit.runner.RunWith; -import org.openqa.selenium.By; -import org.openqa.selenium.NoSuchElementException; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.remote.RemoteWebDriver; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.context.WebServerInitializedEvent; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ApplicationListener; -import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.util.Assert; -import org.testcontainers.Testcontainers; -import org.testcontainers.containers.BrowserWebDriverContainer; -import org.testcontainers.containers.Container; -import org.testcontainers.containers.GenericContainer; + +import static org.cbioportal.test.integration.security.ContainerConfig.MyMysqlInitializer; +import static org.cbioportal.test.integration.security.ContainerConfig.MyOAuth2KeycloakInitializer; +import static org.cbioportal.test.integration.security.ContainerConfig.PortInitializer; @RunWith(SpringRunner.class) @SpringBootTest( @@ -47,157 +21,60 @@ ) @TestPropertySource( properties = { - "app.name=cbioportal", - "server.port=8080", - "filter_groups_by_appname=false", "authenticate=oauth2", "dat.method=oauth2", // DB settings (also see MysqlInitializer) "spring.datasource.driverClassName=com.mysql.jdbc.Driver", "spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect", // OAuth2 settings - "spring.security.oauth2.client.registration.cbio-idp.redirect-uri=http://host.testcontainers.internal:8080/login/oauth2/code/cbio-idp", - "spring.security.oauth2.client.provider.cbio-idp.user-name-attribute=email", - "spring.security.oauth2.client.registration.cbio-idp.client-name=cbioportal_oauth2", - "spring.security.oauth2.client.registration.cbio-idp.client-id=cbioportal_oauth2", - "spring.security.oauth2.client.registration.cbio-idp.client-secret=client_secret", - "spring.security.oauth2.client.registration.cbio-idp.authorization-grant-type=authorization_code", - "spring.security.oauth2.client.registration.cbio-idp.client-authentication-method=client_secret_post", - "spring.security.oauth2.client.registration.cbio-idp.scope=openid,email,roles", - "spring.security.oauth2.client.user-info-roles-path=resource_access::cbioportal::roles", + "spring.security.oauth2.client.provider.keycloak.user-name-attribute=email", + "spring.security.oauth2.client.registration.keycloak.client-name=cbioportal_oauth2", + "spring.security.oauth2.client.registration.keycloak.client-id=cbioportal_oauth2", + "spring.security.oauth2.client.registration.keycloak.client-secret=client_secret", + "spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code", + "spring.security.oauth2.client.registration.keycloak.client-authentication-method=client_secret_post", + "spring.security.oauth2.client.registration.keycloak.scope=openid,email,roles", + "spring.security.oauth2.client.jwt-roles-path=resource_access::cbioportal::roles", // Keycloak host settings (also see KeycloakInitializer) "dat.oauth2.clientId=cbioportal_oauth2", "dat.oauth2.clientSecret=client_secret", // Redirect URL to cBiopPortal application from perspective of browser - "dat.oauth2.redirectUri=http://host.testcontainers.internal:8080/api/data-access-token/oauth2", - "dat.oauth2.jwtRolesPath=resource_access::cbioportal::roles" + "dat.oauth2.redirectUri=http://localhost:8080/api/data-access-token/oauth2", + "dat.oauth2.jwtRolesPath=resource_access::cbioportal::roles", + "session.service.url=http://localhost:5000/api/sessions/my_portal/", + "filter_groups_by_appname=false" + } ) @ContextConfiguration(initializers = { - MyMysqlInitializer.class, - MyKeycloakInitializer.class, + MyMysqlInitializer.class, + MyOAuth2KeycloakInitializer.class, PortInitializer.class }) -@Ignore -public class OAuth2AuthIntegrationTest { +@DirtiesContext +public class OAuth2AuthIntegrationTest extends ContainerConfig { - private final static int CBIO_PORT = 8080; public final static String CBIO_URL_FROM_BROWSER = - String.format("http://host.testcontainers.internal:%d", CBIO_PORT); - - @Autowired - private ApplicationContext context; - - @ClassRule - public static SharedMysqlContainer mysqlContainer = SharedMysqlContainer.getInstance(); - - @ClassRule - public static KeycloakContainer keycloakContainer = SharedKeycloakContainer.getInstance(); - - @ClassRule - public static BrowserWebDriverContainer chrome = SharedChromeContainer.getInstance(); - - // Update application properties with connection info on Keycloak container - public static class MyKeycloakInitializer extends OAuth2KeycloakInitializer { - @Override - public void initialize( - ConfigurableApplicationContext configurableApplicationContext) { - super.initializeImpl(configurableApplicationContext, keycloakContainer); - } - } - - // Update application properties with connection info on Mysql container - public static class MyMysqlInitializer extends MysqlInitializer { - @Override - public void initialize( - ConfigurableApplicationContext configurableApplicationContext) { - super.initializeImpl(configurableApplicationContext, mysqlContainer); - } - } - - // Expose the ports for the cBioPortal Spring application and keycloak inside - // the Chrome container. Each address is available on http://host.testcontainers.internal: - // in the browser container. - public static class PortInitializer implements - ApplicationContextInitializer { - @Override - public void initialize(ConfigurableApplicationContext applicationContext) { - applicationContext.addApplicationListener( - (ApplicationListener) event -> { - Testcontainers.exposeHostPorts(CBIO_PORT, keycloakContainer.getHttpPort()); - }); - } - } - + String.format("http://localhost:%d", CBIO_PORT); + @Test - public void loginSuccess() { - RemoteWebDriver driver = performLogin(); - WebElement loggedInButton = driver.findElement(By.id("dat-dropdown")); - Assertions.assertEquals("Logged in as testuser@thehyve.nl", loggedInButton.getText()); - Assertions.assertDoesNotThrow( - () -> driver.findElement(By.xpath("//span[.='Breast Invasive Carcinoma (TCGA,Nature 2012)']")), - "Study could not be found on the landing page. Permissions are not correctly passed from IDP to client."); + public void a_loginSuccess() { + Util.testLogin(CBIO_URL_FROM_BROWSER, chromeDriver); } - + @Test - public void downloadOfflineToken() throws Exception { - RemoteWebDriver driver = performLogin(); - Assertions.assertDoesNotThrow( - () -> driver.findElement(By.id("dat-dropdown")).click(), - "Logged-in menu could not be found on the page."); - driver.findElement(By.linkText("Data Access Token")).click(); - driver.findElement(By.xpath("//button[text()='Download Token']")).click(); - - await().atMost(Duration.ofSeconds(2)).until(downloadedFile()); - - Assertions.assertTrue(downloadedFile().call()); + public void b_downloadOfflineToken() throws Exception { + Util.testDownloadOfflineToken(CBIO_URL_FROM_BROWSER, chromeDriver); } @Test - public void logoutSuccess() { - RemoteWebDriver driver = performLogin(); - Assertions.assertDoesNotThrow( - () -> driver.findElement(By.id("dat-dropdown")).click(), - "Logout menu could not be found on the page."); - driver.findElement(By.linkText("Sign out")).click(); - Assertions.assertDoesNotThrow( - () -> driver.findElement(By.id("username")), - "IDP login screen not visible on the page. Logout did not work correctly." - ); + public void c_logoutSuccess() { + Util.testOAuthLogout(CBIO_URL_FROM_BROWSER, chromeDriver); } - private RemoteWebDriver performLogin() { - RemoteWebDriver driver = chrome.getWebDriver(); - driver.get(CBIO_URL_FROM_BROWSER); - try { - // when the cbioportal logo is visible, skip login - driver.findElement(By.id("cbioportal-logo")); - } catch (NoSuchElementException e) { - WebElement userNameInput = driver.findElement(By.id("username")); - WebElement passwordInput = driver.findElement(By.id("password")); - WebElement loginButton = driver.findElement(By.id("kc-login")); - userNameInput.sendKeys("testuser"); - passwordInput.sendKeys("P@ssword1"); - loginButton.click(); - } - return driver; - } - - private boolean containerFileExists( - @Nonnull final GenericContainer container, @Nonnull String path) - throws IOException, InterruptedException { - Assert.notNull(container, "Containers is null"); - Assert.isTrue(!path.isEmpty(), "Path string is empty"); - Container.ExecResult r = container.execInContainer("/bin/sh", "-c", - "if [ -f " + path - + " ] ; then echo '0' ; else (>&2 echo '1') ; fi"); - return !r.getStderr().contains("1"); - } - - private Callable downloadedFile() { - return () -> containerFileExists(chrome, - String.format("%s/cbioportal_data_access_token.txt", - SharedChromeContainer.DOWNLOAD_FOLDER)); + @Test + public void d_loginAgainSuccess() { + Util.testLoginAgain(CBIO_URL_FROM_BROWSER, chromeDriver); } - + } \ No newline at end of file diff --git a/src/test/java/org/cbioportal/test/integration/security/OAuth2ResourceServerIntegrationTest.java b/src/test/java/org/cbioportal/test/integration/security/OAuth2ResourceServerIntegrationTest.java new file mode 100644 index 00000000000..bdb48da1146 --- /dev/null +++ b/src/test/java/org/cbioportal/test/integration/security/OAuth2ResourceServerIntegrationTest.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2019 The Hyve B.V. + * This code is licensed under the GNU Affero General Public License (AGPL), + * version 3, or (at your option) any later version. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.cbioportal.test.integration.security; + + +import org.cbioportal.test.integration.security.util.HttpHelper; +import org.json.JSONArray; +import org.json.JSONException; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.runner.RunWith; +import org.mockserver.client.MockServerClient; +import org.mockserver.model.HttpRequest; +import org.mockserver.model.HttpResponse; +import org.mockserver.model.StringBody; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +import java.io.IOException; +import java.net.URLEncoder; + +import static org.cbioportal.test.integration.security.ContainerConfig.MyMysqlInitializer; +import static org.cbioportal.test.integration.security.ContainerConfig.MyOAuth2ResourceServerKeycloakInitializer; +import static org.cbioportal.test.integration.security.util.TokenHelper.encodeWithoutSigning; +import static org.junit.Assert.assertEquals; + + +/** + * Tests protection of API endpoints by OIDC data access token + */ +@RunWith(SpringRunner.class) +@SpringBootTest( + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT +) +@TestPropertySource( + properties = { + "authenticate=saml", + "dat.method=oauth2", + // DB settings + "spring.datasource.driverClassName=com.mysql.jdbc.Driver", + "spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect", + // FIXME Our test saml idp does not sign assertions for some reason + "spring.security.saml2.relyingparty.registration.keycloak.entity-id=cbioportal", + "spring.security.saml2.relyingparty.registration.keycloak.signing.credentials[0].certificate-location=classpath:dev/security/signing-cert.pem", + "spring.security.saml2.relyingparty.registration.keycloak.signing.credentials[0].private-key-location=classpath:dev/security/signing-key.pem", + "dat.oauth2.clientId=client_id", + "dat.oauth2.clientSecret=client_secret", + "dat.oauth2.redirectUri=http://localhost:8080/api/data-access-token/oauth2", + // host is the mock server that fakes the oidc idp + "dat.oauth2.accessTokenUri=http://localhost:8085/realms/cbio/protocol/openid-connect/token", + "dat.oauth2.userAuthorizationUri=http://localhost:8085/realms/cbio/protocol/openid-connect/auth", + "dat.oauth2.jwtRolesPath=resource_access::cbioportal::roles", + "filter_groups_by_appname=false" + } +) +@ContextConfiguration(initializers = { + MyMysqlInitializer.class, + MyOAuth2ResourceServerKeycloakInitializer.class +}) +@DirtiesContext +public class OAuth2ResourceServerIntegrationTest extends ContainerConfig { + + public final static String CBIO_URL_FROM_BROWSER = + String.format("http://localhost:%d", CBIO_PORT); + + private final static String tokenUriPath = "/realms/cbio/protocol/openid-connect/token"; + + @Test + public void testAccessForbiddenForAnonymousUser() throws IOException { + HttpHelper.HttpResponse response = HttpHelper.sendGetRequest(CBIO_URL_FROM_BROWSER + "/api/studies", null, null); + assertEquals(401, response.code); + } + + @Test + public void testAccessForbiddenForFakeBearerToken() throws IOException { + MockServerClient mockServerClient = new MockServerClient(mockServerContainer.getHost(), mockServerContainer.getFirstMappedPort()); + String offlineToken = "{\"sub\": \"0000000000\"}"; + String encodedOfflineToken = encodeWithoutSigning(offlineToken); + mockServerClient.when( + HttpRequest.request() + .withMethod("POST") + .withPath(tokenUriPath) + .withBody(StringBody.subString("refresh_token=" + URLEncoder.encode(encodedOfflineToken, "UTF-8")))) + .respond(HttpResponse.response().withStatusCode(401)); + HttpHelper.HttpResponse response = HttpHelper.sendGetRequest(CBIO_URL_FROM_BROWSER + "/api/studies", encodedOfflineToken, null); + assertEquals(401, response.code); + } + + @Test + public void testAccessForValidBearerToken() throws IOException, JSONException { + + String offlineTokenClaims = "{\"sub\": \"1234567890\"}"; + String encodedOfflineToken = encodeWithoutSigning(offlineTokenClaims); + String accessTokenClaims = "{" + + "\"sub\": \"1234567890\"," + + "\"name\": \"John Doe\"," + + "\"resource_access\": {\"cbioportal\": {\"roles\": [\"study_tcga_pub\"]}}" + + "}"; + MockServerClient mockServerClient = new MockServerClient(mockServerContainer.getHost(), mockServerContainer.getFirstMappedPort()); + mockServerClient.when( + HttpRequest.request() + .withMethod("POST") + .withPath(tokenUriPath) + .withBody(StringBody.subString("refresh_token=" + URLEncoder.encode(encodedOfflineToken, "UTF-8")))) + .respond( + HttpResponse.response() + .withBody("{\"access_token\": \"" + + encodeWithoutSigning(accessTokenClaims) + + "\"}")); + HttpHelper.HttpResponse response = HttpHelper.sendGetRequest(CBIO_URL_FROM_BROWSER + "/api/studies", encodedOfflineToken, null); + + assertEquals(200, response.code); + Assertions.assertTrue(response.body != null && !response.body.isEmpty()); + JSONArray studies = new JSONArray(response.body); + Assertions.assertEquals(1, studies.length()); + studies.getJSONObject(0).getString("studyId"); + Assertions.assertEquals("study_tcga_pub", studies.getJSONObject(0).getString("studyId")); + } + +} diff --git a/src/test/java/org/cbioportal/test/integration/security/Oauth2ResourceServerIntegrationTest.java b/src/test/java/org/cbioportal/test/integration/security/Oauth2ResourceServerIntegrationTest.java deleted file mode 100644 index acd4c36d97c..00000000000 --- a/src/test/java/org/cbioportal/test/integration/security/Oauth2ResourceServerIntegrationTest.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2019 The Hyve B.V. - * This code is licensed under the GNU Affero General Public License (AGPL), - * version 3, or (at your option) any later version. - */ - -/* - * This file is part of cBioPortal. - * - * cBioPortal is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.cbioportal.test.integration.security; - - -import static org.cbioportal.test.integration.security.Oauth2ResourceServerIntegrationTest.*; -import static org.cbioportal.test.integration.security.util.TokenHelper.encodeWithoutSigning; -import static org.junit.Assert.assertEquals; - - -import java.io.IOException; -import java.net.URLEncoder; -import org.cbioportal.PortalApplication; -import org.cbioportal.test.integration.MysqlInitializer; -import org.cbioportal.test.integration.SharedMysqlContainer; -import org.cbioportal.test.integration.security.util.HttpHelper; -import org.json.JSONArray; -import org.json.JSONException; -import org.junit.*; -import org.junit.jupiter.api.Assertions; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit4.SpringRunner; - - -/** - * Tests protection of API endpoints by SAML auth - */ -// This starts a live portal instance on a random port (imported via @LocalServerPort) -@RunWith(SpringRunner.class) -@SpringBootTest( - webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, - classes = {PortalApplication.class} -) -@TestPropertySource( - properties = { - "app.name=cbioportal", - "server.port=8080", - "filter_groups_by_appname=true", - "authenticate=saml", - "dat.method=oauth2", - // DB settings - "spring.datasource.driverClassName=com.mysql.jdbc.Driver", - "spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect", - // SAML settings - "saml.keystore.location=classpath:/security/samlKeystore.jks", - "saml.keystore.password=P@ssword1", - "saml.keystore.private-key.key=secure-key", - "saml.keystore.private-key.password=P@ssword1", - "saml.keystore.default-key=secure-key", - "saml.idp.metadata.location=classpath:/security/saml-idp-metadata.xml", - // I had to use specificBinding because of this bug https://github.com/spring-projects/spring-security-saml/issues/460 - "saml.idp.comm.binding.settings=specificBinding", - "saml.idp.comm.binding.type=bindings:HTTP-Redirect", - "saml.sp.metadata.entitybaseurl=#{null}", - "saml.sp.metadata.entityid=cbioportal", - "saml.idp.metadata.entityid=spring.security.saml.idp.id", - "saml.idp.metadata.attribute.email=User.email", - "saml.custom.userservice.class=org.cbioportal.security.spring.authentication.saml.SAMLUserDetailsServiceImpl", - "saml.logout.local=false", - // FIXME Our test saml idp does not sign assertions for some reason - "saml.sp.metadata.wantassertionsigned=false", - "dat.oauth2.clientId=client_id", - "dat.oauth2.clientSecret=client_secret", - "dat.oauth2.issuer=token_issuer", - "dat.oauth2.accessTokenUri=http://localhost:8443/auth/realms/cbio/token", - "dat.oauth2.redirectUri=http://localhost:8080/api/data-access-token/oauth2", - "dat.oauth2.userAuthorizationUri=http://localhost:8443/auth/realms/cbio/auth", - "dat.oauth2.jwkUrl=http://localhost:8443/auth/realms/cbio/jwkUrl", - "dat.oauth2.jwtRolesPath=resource_access::cbioportal::roles" - } -) -@ContextConfiguration(initializers = { - MyMysqlInitializer.class, -}) -@Ignore -public class Oauth2ResourceServerIntegrationTest { - - private static String HOST = "http://localhost:8080"; - private static final int IDP_PORT = 8443; - - @ClassRule - public static SharedMysqlContainer mysqlContainer = SharedMysqlContainer.getInstance(); - - // Update application properties with connection info on Mysql container - public static class MyMysqlInitializer extends MysqlInitializer { - @Override - public void initialize( - ConfigurableApplicationContext configurableApplicationContext) { - super.initializeImpl(configurableApplicationContext, mysqlContainer); - } - } - - @Test - public void testAccessForbiddenForAnonymousUser() throws IOException { - HttpHelper.HttpResponse response = HttpHelper.sendGetRequest(HOST + "/api/studies", null, null); - assertEquals(401, response.code); - } - - @Test - public void testAccessForbiddenForFakeBearerToken() throws IOException { - String offlineToken = "{\"sub\": \"0000000000\"}"; - String encodedOfflineToken = encodeWithoutSigning(offlineToken); -// new MockServerClient("localhost", IDP_PORT).when( -// HttpRequest.request() -// .withMethod("POST") -// .withPath("/auth/realms/cbio/token") -// .withBody(StringBody.subString("refresh_token=" + URLEncoder.encode(encodedOfflineToken, "UTF-8")))) -// .respond(HttpResponse.response().withStatusCode(401)); - - HttpHelper.HttpResponse response = HttpHelper.sendGetRequest(HOST + "/api/studies", encodedOfflineToken, null); - - assertEquals(401, response.code); - } - - @Test - public void testAccessForValidBearerToken() throws IOException, JSONException { - String offlineTokenClaims = "{\"sub\": \"1234567890\"}"; - String encodedOfflineToken = encodeWithoutSigning(offlineTokenClaims); - String accessTokenClaims = "{" + - "\"sub\": \"1234567890\"," + - "\"name\": \"John Doe\"," + - "\"resource_access\": {\"cbioportal\": {\"roles\": [\"cbioportal:study_tcga_pub\"]}}" + - "}"; -// new MockServerClient("localhost", IDP_PORT).when( -// HttpRequest.request() -// .withMethod("POST") -// .withPath("/auth/realms/cbio/token") -// .withBody(StringBody.subString("refresh_token=" + URLEncoder.encode(encodedOfflineToken, "UTF-8")))) -// .respond( -// HttpResponse.response() -// .withBody("{\"access_token\": \"" -// + encodeWithoutSigning(accessTokenClaims) -// + "\"}")); - - HttpHelper.HttpResponse response = HttpHelper.sendGetRequest(HOST + "/api/studies", encodedOfflineToken, null); - - assertEquals(200, response.code); - Assertions.assertTrue(response.body != null && !response.body.isEmpty()); - JSONArray studies = new JSONArray(response.body); - Assertions.assertEquals(1, studies.length()); - studies.getJSONObject(0).getString("studyId"); - Assertions.assertEquals("study_tcga_pub", studies.getJSONObject(0).getString("studyId")); - } - - //private static ClientAndServer mockServer; - - //@BeforeClass - //public static void startServer() { - // mockServer = ClientAndServer.startClientAndServer(IDP_PORT); - //} - - //@AfterClass - //public static void stopServer() { - // mockServer.stop(); - //} -} diff --git a/src/test/java/org/cbioportal/test/integration/security/SamlAuthIntegrationTest.java b/src/test/java/org/cbioportal/test/integration/security/SamlAuthIntegrationTest.java index abbf256d725..cefa6844f2c 100644 --- a/src/test/java/org/cbioportal/test/integration/security/SamlAuthIntegrationTest.java +++ b/src/test/java/org/cbioportal/test/integration/security/SamlAuthIntegrationTest.java @@ -1,72 +1,45 @@ package org.cbioportal.test.integration.security; -import static org.cbioportal.test.integration.security.SamlAuthIntegrationTest.MySamlKeycloakInitializer; -import static org.cbioportal.test.integration.security.SamlAuthIntegrationTest.MyMysqlInitializer; -import static org.cbioportal.test.integration.security.SamlAuthIntegrationTest.PortInitializer; -import static org.testcontainers.shaded.org.awaitility.Awaitility.await; - - -import dasniko.testcontainers.keycloak.KeycloakContainer; -import java.io.IOException; -import java.time.Duration; -import java.util.concurrent.Callable; -import javax.annotation.Nonnull; -import org.cbioportal.PortalApplication; -import org.cbioportal.test.integration.SamlKeycloakInitializer; -import org.cbioportal.test.integration.MysqlInitializer; -import org.cbioportal.test.integration.SharedChromeContainer; -import org.cbioportal.test.integration.SharedKeycloakContainer; -import org.cbioportal.test.integration.SharedMysqlContainer; -import org.junit.ClassRule; -import org.junit.Ignore; +import org.cbioportal.test.integration.security.util.Util; import org.junit.Test; -import org.junit.jupiter.api.Assertions; import org.junit.runner.RunWith; -import org.openqa.selenium.By; -import org.openqa.selenium.NoSuchElementException; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.remote.RemoteWebDriver; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.context.WebServerInitializedEvent; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ApplicationListener; -import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.util.Assert; -import org.testcontainers.Testcontainers; -import org.testcontainers.containers.BrowserWebDriverContainer; -import org.testcontainers.containers.Container; -import org.testcontainers.containers.GenericContainer; + +import static org.cbioportal.test.integration.security.ContainerConfig.MyMysqlInitializer; +import static org.cbioportal.test.integration.security.ContainerConfig.MySamlKeycloakInitializer; +import static org.cbioportal.test.integration.security.ContainerConfig.PortInitializer; @RunWith(SpringRunner.class) @SpringBootTest( - webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, - classes = {PortalApplication.class} + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT ) @TestPropertySource( properties = { - "app.name=cbioportal", - "server.port=8080", - "filter_groups_by_appname=false", "authenticate=saml", - "dat.method=oauth2", + //"dat.method=oauth2", // DB settings (also see MysqlInitializer) "spring.datasource.driverClassName=com.mysql.jdbc.Driver", "spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect", // SAML settings - "spring.security.saml2.relyingparty.registration.cbio-idp.entity-id=cbioportal", - "spring.security.saml2.relyingparty.registration.cbio-idp.signing.credentials[0].certificate-location=classpath:/security/signing-cert.pem", - "spring.security.saml2.relyingparty.registration.cbio-idp.signing.credentials[0].private-key-location=classpath:/security/signing-key.pem", + "spring.security.saml2.relyingparty.registration.keycloak.entity-id=cbioportal", + "spring.security.saml2.relyingparty.registration.keycloak.signing.credentials[0].certificate-location=classpath:security/signing-cert.pem", + "spring.security.saml2.relyingparty.registration.keycloak.signing.credentials[0].private-key-location=classpath:security/signing-key.pem", "saml.idp.metadata.attribute.email=email", "saml.idp.metadata.attribute.role=Role", + "logging.level.org.springframework.security=Debug", // Keycloak host settings (also see KeycloakInitializer) - "dat.oauth2.clientId=cbioportal_oauth2", - "dat.oauth2.clientSecret=client_secret", + //"dat.oauth2.clientId=cbioportal_oauth2", + //"dat.oauth2.clientSecret=client_secret", // Redirect URL to cBiopPortal application from perspective of browser - "dat.oauth2.redirectUri=http://host.testcontainers.internal:8080/api/data-access-token/oauth2", - "dat.oauth2.jwtRolesPath=resource_access::cbioportal::roles" + //"dat.oauth2.redirectUri=http://host.testcontainers.internal:8080/api/data-access-token/oauth2", + //"dat.oauth2.jwtRolesPath=resource_access::cbioportal::roles", + "security.cors.allowed-origins=*", + "session.service.url=http://localhost:5000/api/sessions/my_portal/", + "filter_groups_by_appname=false" } ) @ContextConfiguration(initializers = { @@ -74,123 +47,25 @@ MySamlKeycloakInitializer.class, PortInitializer.class }) -@Ignore -public class SamlAuthIntegrationTest { +@DirtiesContext +public class SamlAuthIntegrationTest extends ContainerConfig { - private final static int CBIO_PORT = 8080; public final static String CBIO_URL_FROM_BROWSER = - String.format("http://host.testcontainers.internal:%d", CBIO_PORT); - - @ClassRule - public static SharedMysqlContainer mysqlContainer = SharedMysqlContainer.getInstance(); - - @ClassRule - public static KeycloakContainer keycloakContainer = SharedKeycloakContainer.getInstance(); - - @ClassRule - public static BrowserWebDriverContainer chrome = SharedChromeContainer.getInstance(); - - // Update application properties with connection info on Keycloak container - public static class MySamlKeycloakInitializer extends SamlKeycloakInitializer { - @Override - public void initialize( - ConfigurableApplicationContext configurableApplicationContext) { - super.initializeImpl(configurableApplicationContext, keycloakContainer); - } - } - - // Update application properties with connection info on Mysql container - public static class MyMysqlInitializer extends MysqlInitializer { - @Override - public void initialize( - ConfigurableApplicationContext configurableApplicationContext) { - super.initializeImpl(configurableApplicationContext, mysqlContainer); - } - } - - // Expose the ports for the cBioPortal Spring application and keycloak inside - // the Chrome container. Each address is available on http://host.testcontainers.internal: - // in the browser container. - public static class PortInitializer implements - ApplicationContextInitializer { - @Override - public void initialize(ConfigurableApplicationContext applicationContext) { - applicationContext.addApplicationListener( - (ApplicationListener) event -> { - Testcontainers.exposeHostPorts(CBIO_PORT, keycloakContainer.getHttpPort()); - }); - } - } - + String.format("http://localhost:%d", CBIO_PORT); + @Test - public void loginSuccess() { - RemoteWebDriver driver = performLogin(); - WebElement loggedInButton = driver.findElement(By.id("dat-dropdown")); - Assertions.assertEquals("Logged in as testuser@thehyve.nl", loggedInButton.getText()); - Assertions.assertDoesNotThrow( - () -> driver.findElement(By.xpath("//span[.='Breast Invasive Carcinoma (TCGA,Nature 2012)']")), - "Study could not be found on the landing page. Permissions are not correctly passed from IDP to client."); + public void a_loginSuccess() { + Util.testLogin(CBIO_URL_FROM_BROWSER, chromeDriver); } - + @Test - public void downloadOfflineToken() throws Exception { - RemoteWebDriver driver = performLogin(); - Assertions.assertDoesNotThrow( - () -> driver.findElement(By.id("dat-dropdown")).click(), - "Logged-in menu could not be found on the page."); - driver.findElement(By.linkText("Data Access Token")).click(); - driver.findElement(By.xpath("//button[text()='Download Token']")).click(); - - await().atMost(Duration.ofSeconds(5)).until(downloadedFile()); - - Assertions.assertTrue(downloadedFile().call()); + public void b_testAuthorizedStudy() { + Util.testLoginAndVerifyStudyNotPresent(CBIO_URL_FROM_BROWSER,chromeDriver ); } @Test - public void logoutSuccess() { - RemoteWebDriver driver = performLogin(); - Assertions.assertDoesNotThrow( - () -> driver.findElement(By.id("dat-dropdown")).click(), - "Logout menu could not be found on the page."); - driver.findElement(By.linkText("Sign out")).click(); - Assertions.assertDoesNotThrow( - () -> driver.findElement(By.id("username")), - "IDP login screen not visible on the page. Logout did not work correctly." - ); - } - - private RemoteWebDriver performLogin() { - RemoteWebDriver driver = chrome.getWebDriver(); - driver.get(CBIO_URL_FROM_BROWSER); - try { - // when the cbioportal logo is visible, skip login - driver.findElement(By.id("cbioportal-logo")); - } catch (NoSuchElementException e) { - WebElement userNameInput = driver.findElement(By.id("username")); - WebElement passwordInput = driver.findElement(By.id("password")); - WebElement loginButton = driver.findElement(By.id("kc-login")); - userNameInput.sendKeys("testuser"); - passwordInput.sendKeys("P@ssword1"); - loginButton.click(); - } - return driver; - } - - private boolean containerFileExists( - @Nonnull final GenericContainer container, @Nonnull String path) - throws IOException, InterruptedException { - Assert.notNull(container, "Containers is null"); - Assert.isTrue(!path.isEmpty(), "Path string is empty"); - Container.ExecResult r = container.execInContainer("/bin/sh", "-c", - "if [ -f " + path - + " ] ; then echo '0' ; else (>&2 echo '1') ; fi"); - return !r.getStderr().contains("1"); - } - - private Callable downloadedFile() { - return () -> containerFileExists(chrome, - String.format("%s/cbioportal_data_access_token.txt", - SharedChromeContainer.DOWNLOAD_FOLDER)); + public void c_logoutSuccess() { + Util.testSamlLogout(CBIO_URL_FROM_BROWSER, chromeDriver); } } \ No newline at end of file diff --git a/src/test/java/org/cbioportal/test/integration/security/util/Util.java b/src/test/java/org/cbioportal/test/integration/security/util/Util.java new file mode 100644 index 00000000000..91fb5ca6c22 --- /dev/null +++ b/src/test/java/org/cbioportal/test/integration/security/util/Util.java @@ -0,0 +1,121 @@ +package org.cbioportal.test.integration.security.util; + +import org.cbioportal.test.integration.security.ContainerConfig; +import org.junit.jupiter.api.Assertions; +import org.openqa.selenium.By; +import org.openqa.selenium.NoSuchElementException; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.remote.RemoteWebDriver; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; + +import java.io.File; +import java.time.Duration; +import java.util.concurrent.TimeUnit; + +import static org.testcontainers.shaded.org.awaitility.Awaitility.await; + +public class Util { + + public static void testLogin(String cbioUrl, ChromeDriver chromedriver) { + performLogin(cbioUrl, chromedriver); + WebElement loggedInButton = chromedriver.findElement(By.id("dat-dropdown")); + Assertions.assertEquals("Logged in as testuser@thehyve.nl", loggedInButton.getText()); + new WebDriverWait(chromedriver, Duration.ofSeconds(20)).until( + ExpectedConditions.presenceOfElementLocated(By.xpath("//span[.='Breast Invasive Carcinoma (TCGA,Nature 2012)']"))); + Assertions.assertDoesNotThrow( + () -> chromedriver.findElement(By.xpath("//span[.='Breast Invasive Carcinoma (TCGA,Nature 2012)']")), + "Study could not be found on the landing page. Permissions are not correctly passed from IDP to client."); + } + + public static void testLoginAndVerifyStudyNotPresent(String cbioUrl, ChromeDriver chromeDriver) { + performLogin(cbioUrl, chromeDriver); + WebElement loggedInButton = chromeDriver.findElement(By.id("dat-dropdown")); + Assertions.assertEquals("Logged in as testuser@thehyve.nl", loggedInButton.getText()); + new WebDriverWait(chromeDriver, Duration.ofSeconds(20)).until( + ExpectedConditions.presenceOfElementLocated(By.xpath("//span[.='Breast Invasive Carcinoma (TCGA,Nature 2012)']"))); + Assertions.assertThrows( + NoSuchElementException.class, + () -> chromeDriver.findElement(By.xpath("//span[.='Adrenocortical Carcinoma (TCGA, Provisional)']")), + "Study could not be found on the landing page. Permissions are not correctly passed from IDP to client."); + } + + public static void testDownloadOfflineToken(String cbioUrl, ChromeDriver chromeDriver) throws Exception { + performLogin(cbioUrl, chromeDriver); + Assertions.assertDoesNotThrow( + () -> chromeDriver.findElement(By.id("dat-dropdown")).click(), + "Logged-in menu could not be found on the page."); + chromeDriver.findElement(By.linkText("Data Access Token")).click(); + chromeDriver.findElement(By.xpath("//button[text()='Download Token']")).click(); + + var file = new File(String.format("%s/cbioportal_data_access_token.txt", + ContainerConfig.DOWNLOAD_FOLDER)); + await().atMost(Duration.ofSeconds(5)).until(file::exists); + Assertions.assertTrue(file.exists()); + } + + public static void testOAuthLogout(String cbioUrl, ChromeDriver chromeDriver) { + performLogin(cbioUrl, chromeDriver); + Assertions.assertDoesNotThrow( + () -> chromeDriver.findElement(By.id("dat-dropdown")).click(), + "Logout menu could not be found on the page."); + //chromeDriver.findElement(By.linkText("Sign out")).click(); + // TODO: Remove when sync'd with frontend + chromeDriver.get(cbioUrl + "/logout"); + Assertions.assertDoesNotThrow( + () -> chromeDriver.findElement(By.id("username")), + "IDP login screen not visible on the page. Logout did not work correctly."); + } + + public static void testSamlLogout(String cbioUrl, ChromeDriver chromeDriver) { + performLogin(cbioUrl, chromeDriver); + Assertions.assertDoesNotThrow( + () -> chromeDriver.findElement(By.id("dat-dropdown")).click(), + "Logout menu could not be found on the page."); + chromeDriver.findElement(By.linkText("Sign out")).click(); + Assertions.assertDoesNotThrow( + () -> { + chromeDriver.findElement(By.xpath("//button[text()='Login CBioPortal']")); + } + ); + } + + + + public static void testLoginAgain(String cbioUrl, ChromeDriver chromeDriver) { + performLogin(cbioUrl, chromeDriver); + Assertions.assertDoesNotThrow( + () -> chromeDriver.findElement(By.id("dat-dropdown")).click(), + "Logout menu could not be found on the page."); + chromeDriver.get(cbioUrl + "/logout"); + chromeDriver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS); + Assertions.assertDoesNotThrow( + () -> chromeDriver.findElement(By.id("username")), + "IDP login screen not visible on the page. Logout did not work correctly." + ); + performLogin(cbioUrl, chromeDriver); + Assertions.assertDoesNotThrow( + () -> chromeDriver.findElement(By.id("dat-dropdown")), + "Logged-in menu could not be found on the page. Login did not work correctly."); + } + + private static void performLogin(String url, RemoteWebDriver driver) { + driver.get(url); + driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS); + try { + // when the cbioportal logo is visible, skip login + driver.findElement(By.id("cbioportal-logo")); + } catch (NoSuchElementException e) { + WebElement userNameInput = driver.findElement(By.id("username")); + WebElement passwordInput = driver.findElement(By.id("password")); + WebElement loginButton = driver.findElement(By.id("kc-login")); + userNameInput.sendKeys("testuser"); + passwordInput.sendKeys("P@ssword1"); + loginButton.click(); + } + new WebDriverWait(driver, Duration.ofSeconds(20)).until( + ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@data-test='cancerTypeListContainer']"))); + } + +} diff --git a/src/test/java/org/cbioportal/web/DataAccessTokenControllerTest.java b/src/test/java/org/cbioportal/web/DataAccessTokenControllerTest.java index 0240050b039..917a2908184 100644 --- a/src/test/java/org/cbioportal/web/DataAccessTokenControllerTest.java +++ b/src/test/java/org/cbioportal/web/DataAccessTokenControllerTest.java @@ -26,14 +26,13 @@ import org.cbioportal.model.DataAccessToken; import org.cbioportal.service.DataAccessTokenService; import org.cbioportal.service.exception.TokenNotFoundException; +import org.cbioportal.web.config.DataAccessTokenControllerConfig; import org.cbioportal.web.config.DataAccessTokenControllerTestConfig; import org.cbioportal.web.config.TestConfig; import org.junit.Assert; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentMatchers; -import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.springframework.beans.factory.annotation.Autowired; @@ -43,6 +42,7 @@ import org.springframework.mock.web.MockHttpSession; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.web.servlet.MockMvc; @@ -50,10 +50,12 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; +@TestPropertySource(properties = { + "download_group=PLACEHOLDER_ROLE", +}) @RunWith(SpringJUnit4ClassRunner.class) @WebMvcTest @ContextConfiguration(classes = {DataAccessTokenController.class, TestConfig.class, DataAccessTokenControllerTestConfig.class }) -@Ignore public class DataAccessTokenControllerTest { public static final String MOCK_USER = "MOCK_USER"; @@ -173,7 +175,7 @@ public void revokeNonexistentTokenTest() throws Exception { * Tests for 201 (CREATED) response code */ @Test - @WithMockUser + @WithMockUser(username = MOCK_USER, password = MOCK_PASSWORD, authorities = "PLACEHOLDER_ROLE") public void createTokenValidUserTest() throws Exception { when(tokenService.createDataAccessToken(ArgumentMatchers.anyString())).thenReturn(MOCK_TOKEN_INFO); HttpSession session = getSession(MOCK_USER, MOCK_PASSWORD); @@ -188,7 +190,6 @@ public void createTokenValidUserTest() throws Exception { @Test @WithMockUser(username = MOCK_USER, password = MOCK_PASSWORD, authorities = "PLACEHOLDER_ROLE") public void createTokenValidUserTestWithUserRole() throws Exception { - ReflectionTestUtils.setField(DataAccessTokenController.class, "userRoleToAccessToken", "PLACEHOLDER_ROLE"); when(tokenService.createDataAccessToken(ArgumentMatchers.anyString())).thenReturn(MOCK_TOKEN_INFO); HttpSession session = getSession(MOCK_USER, MOCK_PASSWORD); MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/api/data-access-tokens").with(csrf()) @@ -202,7 +203,6 @@ public void createTokenValidUserTestWithUserRole() throws Exception { @Test @WithMockUser public void createTokenUnauthorizedUserTestWithUserRole() throws Exception { - ReflectionTestUtils.setField(DataAccessTokenController.class, "userRoleToAccessToken", "TEST"); when(tokenService.createDataAccessToken(ArgumentMatchers.anyString())).thenReturn(MOCK_TOKEN_INFO); HttpSession session = getSession(MOCK_USER, MOCK_PASSWORD); MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/api/data-access-tokens") @@ -219,7 +219,7 @@ public void createTokenUnauthorizedUserTestWithUserRole() throws Exception { * Checks that correct username argument is passed to service class */ @Test - @WithMockUser(username = MOCK_USER, password = MOCK_PASSWORD) + @WithMockUser(username = MOCK_USER, password = MOCK_PASSWORD, authorities = "PLACEHOLDER_ROLE") public void revokeAllTokensForUserTest() throws Exception { resetReceivedArgument(); Answer tokenServiceRevokeAllTokensAnswer = new Answer() { @@ -246,7 +246,7 @@ public Void answer(InvocationOnMock revokeAllTokensInvocation) { * Checks that correct username argument is passed to service class */ @Test - @WithMockUser(username = MOCK_USER, password = MOCK_PASSWORD) + @WithMockUser(username = MOCK_USER, password = MOCK_PASSWORD, authorities = "PLACEHOLDER_ROLE") public void getAllTokensForUserTest() throws Exception { resetReceivedArgument(); Answer tokenServiceGetAllTokensAnswer = new Answer() { diff --git a/src/test/java/org/cbioportal/web/MutationControllerTest.java b/src/test/java/org/cbioportal/web/MutationControllerTest.java index 9485d91ad70..b68a15106ca 100644 --- a/src/test/java/org/cbioportal/web/MutationControllerTest.java +++ b/src/test/java/org/cbioportal/web/MutationControllerTest.java @@ -1,12 +1,6 @@ package org.cbioportal.web; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; - - import com.fasterxml.jackson.databind.ObjectMapper; -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; import org.cbioportal.model.AlleleSpecificCopyNumber; import org.cbioportal.model.Gene; import org.cbioportal.model.Mutation; @@ -34,6 +28,11 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; +import java.util.ArrayList; +import java.util.List; + +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; + @RunWith(SpringJUnit4ClassRunner.class) @WebMvcTest @ContextConfiguration(classes = {MutationController.class, MutationCountController.class, TestConfig.class}) @@ -140,7 +139,7 @@ public void getMutationsInMolecularProfileBySampleListIdDefaultProjection() thro List mutationList = createExampleMutations(); Mockito.when(mutationService.getMutationsInMolecularProfileBySampleListId(Mockito.any(), - Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any(), Mockito.anyBoolean(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(mutationList); mockMvc.perform(MockMvcRequestBuilders.get("/api/molecular-profiles/test_molecular_profile_id/mutations") @@ -218,7 +217,7 @@ public void getMutationsInMolecularProfileBySampleListIdDetailedProjection() thr List mutationList = createExampleMutationsWithGeneAndAlleleSpecificCopyNumber(); Mockito.when(mutationService.getMutationsInMolecularProfileBySampleListId(Mockito.any(), - Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any(), Mockito.anyBoolean(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(mutationList); mockMvc.perform(MockMvcRequestBuilders.get("/api/molecular-profiles/test_molecular_profile_id/mutations") @@ -422,7 +421,7 @@ public void fetchMutationsInMolecularProfileDefaultProjection() throws Exception List mutationList = createExampleMutations(); Mockito.when(mutationService.fetchMutationsInMolecularProfile(Mockito.any(), - Mockito.any(), Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any(), Mockito.anyBoolean(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(mutationList); @@ -506,7 +505,7 @@ public void fetchMutationsInMolecularProfileDetailedProjection() throws Exceptio List mutationList = createExampleMutationsWithGeneAndAlleleSpecificCopyNumber(); Mockito.when(mutationService.fetchMutationsInMolecularProfile(Mockito.any(), - Mockito.any(), Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any(), Mockito.anyBoolean(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(mutationList); diff --git a/src/test/java/org/cbioportal/web/ServerStatusControllerTest.java b/src/test/java/org/cbioportal/web/ServerStatusControllerTest.java index 16cf9dc1dbe..f4ec9e1da59 100644 --- a/src/test/java/org/cbioportal/web/ServerStatusControllerTest.java +++ b/src/test/java/org/cbioportal/web/ServerStatusControllerTest.java @@ -1,14 +1,13 @@ package org.cbioportal.web; import org.cbioportal.service.ServerStatusService; -import org.cbioportal.service.impl.ServerStatusServiceImpl; import org.junit.Before; import org.junit.Ignore; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @@ -20,7 +19,7 @@ @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration("/applicationContext-web-test.xml") -@Configuration +@TestConfiguration public class ServerStatusControllerTest { @Autowired diff --git a/src/test/java/org/cbioportal/web/StudyViewControllerTest.java b/src/test/java/org/cbioportal/web/StudyViewControllerTest.java index 2dd141225a8..8ba7ab9ce1b 100644 --- a/src/test/java/org/cbioportal/web/StudyViewControllerTest.java +++ b/src/test/java/org/cbioportal/web/StudyViewControllerTest.java @@ -1,18 +1,6 @@ package org.cbioportal.web; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyList; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.anyString; -import static org.mockito.Mockito.when; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; - - import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; import org.cbioportal.model.AlterationCountByGene; import org.cbioportal.model.AlterationFilter; import org.cbioportal.model.ClinicalAttribute; @@ -35,7 +23,6 @@ import org.cbioportal.service.ClinicalAttributeService; import org.cbioportal.service.ClinicalDataService; import org.cbioportal.service.ClinicalEventService; -import org.cbioportal.service.CustomDataService; import org.cbioportal.service.DiscreteCopyNumberService; import org.cbioportal.service.GenePanelService; import org.cbioportal.service.GeneService; @@ -68,9 +55,9 @@ import org.cbioportal.web.util.LogScaleDataBinner; import org.cbioportal.web.util.ScientificSmallDataBinner; import org.cbioportal.web.util.StudyViewFilterApplier; +import org.cbioportal.web.util.StudyViewFilterUtil; import org.junit.Before; import org.junit.Ignore; -import org.cbioportal.web.util.StudyViewFilterUtil; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -81,10 +68,22 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; -import static org.mockito.ArgumentMatchers.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.when; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; @RunWith(SpringJUnit4ClassRunner.class) @WebMvcTest @@ -122,6 +121,7 @@ public class StudyViewControllerTest { private static final String TEST_CNA_ALTERATION_VALUE_1 = "2"; private static final String TEST_CNA_ALTERATION_VALUE_2 = "-2"; private static final String TEST_MOLECULAR_PROFILE_TYPE = "test_molecular_profile_type"; + private static final String TEST_MUTATION_TYPE = "test_mutation_type"; private List filteredSampleIdentifiers = new ArrayList<>(); private List clinicalData = new ArrayList<>(); @@ -186,7 +186,7 @@ public class StudyViewControllerTest { private MockMvc mockMvc; private AlterationFilter alterationFilter = new AlterationFilter(); - + private ArrayList filteredSamples = new ArrayList<>(); @Before @@ -1200,4 +1200,121 @@ public void validateStructVarFilterBothGeneIdAndSpecialValueNull() throws Except .andExpect(MockMvcResultMatchers.status().isBadRequest()); } + @Test + @WithMockUser + public void fetchMutationDataCounts() throws Exception { + + when(studyViewFilterApplier.apply(any())).thenReturn(filteredSampleIdentifiers); + + List genomicDataCountItems = new ArrayList<>(); + + GenomicDataCount genomicDataCount1 = new GenomicDataCount(); + genomicDataCount1.setLabel(TEST_MUTATION_TYPE); + genomicDataCount1.setValue(TEST_MUTATION_TYPE); + genomicDataCount1.setCount(1); + + GenomicDataCount genomicDataCount2 = new GenomicDataCount(); + genomicDataCount2.setLabel(TEST_MUTATION_TYPE); + genomicDataCount2.setValue(TEST_MUTATION_TYPE); + genomicDataCount2.setCount(1); + + GenomicDataCountItem genomicDataCountItem1 = new GenomicDataCountItem(); + List genomicDataCounts1 = new ArrayList<>(); + genomicDataCounts1.add(genomicDataCount1); + genomicDataCounts1.add(genomicDataCount2); + genomicDataCountItem1.setHugoGeneSymbol(TEST_HUGO_GENE_SYMBOL_1); + genomicDataCountItem1.setProfileType(TEST_MOLECULAR_PROFILE_TYPE); + genomicDataCountItem1.setCounts(genomicDataCounts1); + + GenomicDataCountItem genomicDataCountItem2 = new GenomicDataCountItem(); + List genomicDataCounts2 = new ArrayList<>(); + genomicDataCounts2.add(genomicDataCount1); + genomicDataCounts2.add(genomicDataCount2); + genomicDataCountItem2.setHugoGeneSymbol(TEST_HUGO_GENE_SYMBOL_2); + genomicDataCountItem2.setProfileType(TEST_MOLECULAR_PROFILE_TYPE); + genomicDataCountItem2.setCounts(genomicDataCounts2); + + genomicDataCountItems.add(genomicDataCountItem1); + genomicDataCountItems.add(genomicDataCountItem2); + + when(studyViewService.getMutationCountsByGeneSpecific( + anyList(), + anyList(), + anyList(), + any(AlterationFilter.class))) + .thenReturn(genomicDataCountItems); + + when(studyViewService.getMutationTypeCountsByGeneSpecific( + anyList(), + anyList(), + anyList())) + .thenReturn(genomicDataCountItems); + + GenomicDataCountFilter genomicDataCountFilter = new GenomicDataCountFilter(); + List genomicDataFilters = new ArrayList<>(); + + GenomicDataFilter genomicDataFilter1 = new GenomicDataFilter(); + genomicDataFilter1.setHugoGeneSymbol(TEST_HUGO_GENE_SYMBOL_1); + genomicDataFilter1.setProfileType(TEST_MOLECULAR_PROFILE_TYPE); + genomicDataFilters.add(genomicDataFilter1); + + genomicDataCountFilter.setGenomicDataFilters(genomicDataFilters); + + StudyViewFilter studyViewFilter = new StudyViewFilter(); + studyViewFilter.setStudyIds(Arrays.asList(TEST_STUDY_ID)); + studyViewFilter.setAlterationFilter(alterationFilter); + genomicDataCountFilter.setStudyViewFilter(studyViewFilter); + + ResultActions result1 = mockMvc.perform(MockMvcRequestBuilders.post("/api/mutation-data-counts/fetch").with(csrf()) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .param("projection", "SUMMARY") + .content(objectMapper.writeValueAsString(genomicDataCountFilter))); + + result1 + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) + .andExpect(MockMvcResultMatchers.jsonPath("$[0].hugoGeneSymbol").value(TEST_HUGO_GENE_SYMBOL_1)) + .andExpect(MockMvcResultMatchers.jsonPath("$[0].profileType").value(TEST_MOLECULAR_PROFILE_TYPE)) + .andExpect(MockMvcResultMatchers.jsonPath("$[0].counts[0].label").value(TEST_MUTATION_TYPE)) + .andExpect(MockMvcResultMatchers.jsonPath("$[0].counts[0].value").value(TEST_MUTATION_TYPE)) + .andExpect(MockMvcResultMatchers.jsonPath("$[0].counts[0].count").value(1)) + .andExpect(MockMvcResultMatchers.jsonPath("$[0].counts[1].label").value(TEST_MUTATION_TYPE)) + .andExpect(MockMvcResultMatchers.jsonPath("$[0].counts[1].value").value(TEST_MUTATION_TYPE)) + .andExpect(MockMvcResultMatchers.jsonPath("$[0].counts[1].count").value(1)) + .andExpect(MockMvcResultMatchers.jsonPath("$[1].hugoGeneSymbol").value(TEST_HUGO_GENE_SYMBOL_2)) + .andExpect(MockMvcResultMatchers.jsonPath("$[1].profileType").value(TEST_MOLECULAR_PROFILE_TYPE)) + .andExpect(MockMvcResultMatchers.jsonPath("$[1].counts[0].label").value(TEST_MUTATION_TYPE)) + .andExpect(MockMvcResultMatchers.jsonPath("$[1].counts[0].value").value(TEST_MUTATION_TYPE)) + .andExpect(MockMvcResultMatchers.jsonPath("$[1].counts[0].count").value(1)) + .andExpect(MockMvcResultMatchers.jsonPath("$[1].counts[1].label").value(TEST_MUTATION_TYPE)) + .andExpect(MockMvcResultMatchers.jsonPath("$[1].counts[1].value").value(TEST_MUTATION_TYPE)) + .andExpect(MockMvcResultMatchers.jsonPath("$[1].counts[1].count").value(1)); + + ResultActions result2 = mockMvc.perform(MockMvcRequestBuilders.post("/api/mutation-data-counts/fetch").with(csrf()) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .param("projection", "DETAILED") + .content(objectMapper.writeValueAsString(genomicDataCountFilter))); + + result2 + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) + .andExpect(MockMvcResultMatchers.jsonPath("$[0].hugoGeneSymbol").value(TEST_HUGO_GENE_SYMBOL_1)) + .andExpect(MockMvcResultMatchers.jsonPath("$[0].profileType").value(TEST_MOLECULAR_PROFILE_TYPE)) + .andExpect(MockMvcResultMatchers.jsonPath("$[0].counts[0].label").value(TEST_MUTATION_TYPE)) + .andExpect(MockMvcResultMatchers.jsonPath("$[0].counts[0].value").value(TEST_MUTATION_TYPE)) + .andExpect(MockMvcResultMatchers.jsonPath("$[0].counts[0].count").value(1)) + .andExpect(MockMvcResultMatchers.jsonPath("$[0].counts[1].label").value(TEST_MUTATION_TYPE)) + .andExpect(MockMvcResultMatchers.jsonPath("$[0].counts[1].value").value(TEST_MUTATION_TYPE)) + .andExpect(MockMvcResultMatchers.jsonPath("$[0].counts[1].count").value(1)) + .andExpect(MockMvcResultMatchers.jsonPath("$[1].hugoGeneSymbol").value(TEST_HUGO_GENE_SYMBOL_2)) + .andExpect(MockMvcResultMatchers.jsonPath("$[1].profileType").value(TEST_MOLECULAR_PROFILE_TYPE)) + .andExpect(MockMvcResultMatchers.jsonPath("$[1].counts[0].label").value(TEST_MUTATION_TYPE)) + .andExpect(MockMvcResultMatchers.jsonPath("$[1].counts[0].value").value(TEST_MUTATION_TYPE)) + .andExpect(MockMvcResultMatchers.jsonPath("$[1].counts[0].count").value(1)) + .andExpect(MockMvcResultMatchers.jsonPath("$[1].counts[1].label").value(TEST_MUTATION_TYPE)) + .andExpect(MockMvcResultMatchers.jsonPath("$[1].counts[1].value").value(TEST_MUTATION_TYPE)) + .andExpect(MockMvcResultMatchers.jsonPath("$[1].counts[1].count").value(1)); + } } diff --git a/src/test/java/org/cbioportal/web/config/CacheMapUtilConfig.java b/src/test/java/org/cbioportal/web/config/CacheMapUtilConfig.java index 331e46f6b1b..fe044aec44f 100644 --- a/src/test/java/org/cbioportal/web/config/CacheMapUtilConfig.java +++ b/src/test/java/org/cbioportal/web/config/CacheMapUtilConfig.java @@ -26,6 +26,7 @@ import org.cbioportal.persistence.cachemaputil.CacheMapUtil; import org.cbioportal.service.StaticDataTimestampService; import org.mockito.Mockito; +import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -33,7 +34,7 @@ * * @author ochoaa */ -@Configuration +@TestConfiguration public class CacheMapUtilConfig { @Bean public CacheMapUtil cacheMapUtil() { diff --git a/src/test/java/org/cbioportal/web/config/DataAccessTokenControllerConfig.java b/src/test/java/org/cbioportal/web/config/DataAccessTokenControllerConfig.java index 576ae438af0..cf4f53f3efb 100644 --- a/src/test/java/org/cbioportal/web/config/DataAccessTokenControllerConfig.java +++ b/src/test/java/org/cbioportal/web/config/DataAccessTokenControllerConfig.java @@ -34,16 +34,15 @@ import org.cbioportal.service.DataAccessTokenService; import org.cbioportal.web.DataAccessTokenController; - import org.mockito.Mockito; +import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; /** * * @author ochoaa */ -@Configuration +@TestConfiguration public class DataAccessTokenControllerConfig { @Bean @@ -51,8 +50,4 @@ public DataAccessTokenService tokenService() { return Mockito.mock(DataAccessTokenService.class); } - @Bean - public DataAccessTokenController dataAccessTokenController() { - return new DataAccessTokenController(); - } } diff --git a/src/test/java/org/cbioportal/web/config/RestAuthenticationEntryPoint.java b/src/test/java/org/cbioportal/web/config/RestAuthenticationEntryPoint.java index ee90a9b3549..7984d3445df 100644 --- a/src/test/java/org/cbioportal/web/config/RestAuthenticationEntryPoint.java +++ b/src/test/java/org/cbioportal/web/config/RestAuthenticationEntryPoint.java @@ -39,9 +39,7 @@ import jakarta.servlet.http.HttpServletResponse; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.stereotype.Component; -@Component public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override @@ -50,5 +48,4 @@ public void commence(HttpServletRequest request, HttpServletResponse response, response.sendError( HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized" ); } - } diff --git a/src/test/java/org/cbioportal/web/util/StudyViewFilterApplierTest.java b/src/test/java/org/cbioportal/web/util/StudyViewFilterApplierTest.java index ece4df04682..d71ea23157c 100644 --- a/src/test/java/org/cbioportal/web/util/StudyViewFilterApplierTest.java +++ b/src/test/java/org/cbioportal/web/util/StudyViewFilterApplierTest.java @@ -1,8 +1,20 @@ package org.cbioportal.web.util; import com.fasterxml.jackson.databind.ObjectMapper; -import org.cbioportal.model.*; +import org.cbioportal.model.CNA; +import org.cbioportal.model.ClinicalAttribute; +import org.cbioportal.model.ClinicalData; +import org.cbioportal.model.DiscreteCopyNumberData; +import org.cbioportal.model.Gene; +import org.cbioportal.model.GeneFilter; +import org.cbioportal.model.GeneFilterQuery; +import org.cbioportal.model.GenericAssayData; +import org.cbioportal.model.MolecularProfile; import org.cbioportal.model.MolecularProfile.MolecularAlterationType; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.model.Mutation; +import org.cbioportal.model.Patient; +import org.cbioportal.model.Sample; import org.cbioportal.model.util.Select; import org.cbioportal.service.ClinicalAttributeService; import org.cbioportal.service.ClinicalDataService; @@ -20,10 +32,13 @@ import org.cbioportal.service.impl.CustomDataServiceImpl; import org.cbioportal.service.util.MolecularProfileUtil; import org.cbioportal.service.util.SessionServiceRequestHandler; +import org.cbioportal.web.config.TestConfig; import org.cbioportal.web.parameter.ClinicalDataFilter; import org.cbioportal.web.parameter.DataFilterValue; import org.cbioportal.web.parameter.GeneIdType; import org.cbioportal.web.parameter.GenericAssayDataFilter; +import org.cbioportal.web.parameter.MutationDataFilter; +import org.cbioportal.web.parameter.MutationOption; import org.cbioportal.web.parameter.Projection; import org.cbioportal.web.parameter.SampleIdentifier; import org.cbioportal.web.parameter.StudyViewFilter; @@ -35,21 +50,31 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.util.ResourceUtils; import java.io.IOException; import java.math.BigDecimal; import java.nio.file.Files; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; import static com.google.common.collect.ImmutableList.of; -import static com.google.common.collect.Lists.newArrayList; -import static java.util.stream.Collectors.*; -import static org.mockito.ArgumentMatchers.*; +import static java.util.stream.Collectors.toList; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.when; -@RunWith(MockitoJUnitRunner.Silent.class) +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = TestConfig.class) public class StudyViewFilterApplierTest { public static final String STUDY_ID = "study_id"; @@ -72,9 +97,14 @@ public class StudyViewFilterApplierTest { public static final String HUGO_GENE_SYMBOL_2 = "HUGO_GENE_SYMBOL_2"; public static final String MOLECULAR_PROFILE_ID_1 = "molecular_profile_id1"; public static final String MOLECULAR_PROFILE_ID_2 = "molecular_profile_id2"; + public static final String MUTATION_TYPE_1 = "mutation_type_1"; + public static final String MUTATION_TYPE_2 = "mutation_type_2"; @InjectMocks private StudyViewFilterApplier studyViewFilterApplier; + + @Mock + private ApplicationContext applicationContext; @Mock private SampleService sampleService; @@ -138,11 +168,12 @@ public class StudyViewFilterApplierTest { @Before public void setup() { MockitoAnnotations.initMocks(this); + when(applicationContext.getBean(StudyViewFilterApplier.class)).thenReturn(studyViewFilterApplier); } @Test public void apply() throws Exception { - + List studyIds = new ArrayList<>(); studyIds.add(STUDY_ID); studyIds.add(STUDY_ID); @@ -912,6 +943,139 @@ public void applyCategoricalCustomDataFilter() throws Exception { Assert.assertEquals(1, result.size()); } + @Test + public void applyMutationDataFilter() throws Exception { + + List studyIds = Collections.nCopies(5, STUDY_ID); + + StudyViewFilter studyViewFilter = new StudyViewFilter(); + List sampleIds = new ArrayList<>(); + sampleIds.add(SAMPLE_ID1); + sampleIds.add(SAMPLE_ID2); + sampleIds.add(SAMPLE_ID3); + sampleIds.add(SAMPLE_ID4); + sampleIds.add(SAMPLE_ID5); + + List sampleIdentifiers = new ArrayList<>(); + SampleIdentifier sampleIdentifier1 = new SampleIdentifier(); + sampleIdentifier1.setSampleId(SAMPLE_ID1); + sampleIdentifier1.setStudyId(STUDY_ID); + sampleIdentifiers.add(sampleIdentifier1); + SampleIdentifier sampleIdentifier2 = new SampleIdentifier(); + sampleIdentifier2.setSampleId(SAMPLE_ID2); + sampleIdentifier2.setStudyId(STUDY_ID); + sampleIdentifiers.add(sampleIdentifier2); + SampleIdentifier sampleIdentifier3 = new SampleIdentifier(); + sampleIdentifier3.setSampleId(SAMPLE_ID3); + sampleIdentifier3.setStudyId(STUDY_ID); + sampleIdentifiers.add(sampleIdentifier3); + SampleIdentifier sampleIdentifier4 = new SampleIdentifier(); + sampleIdentifier4.setSampleId(SAMPLE_ID4); + sampleIdentifier4.setStudyId(STUDY_ID); + sampleIdentifiers.add(sampleIdentifier4); + SampleIdentifier sampleIdentifier5 = new SampleIdentifier(); + sampleIdentifier5.setSampleId(SAMPLE_ID5); + sampleIdentifier5.setStudyId(STUDY_ID); + sampleIdentifiers.add(sampleIdentifier5); + studyViewFilter.setSampleIdentifiers(sampleIdentifiers); + + List samples = new ArrayList<>(); + Sample sample1 = new Sample(); + sample1.setStableId(SAMPLE_ID1); + sample1.setCancerStudyIdentifier(STUDY_ID); + samples.add(sample1); + Sample sample2 = new Sample(); + sample2.setStableId(SAMPLE_ID2); + sample2.setCancerStudyIdentifier(STUDY_ID); + samples.add(sample2); + Sample sample3 = new Sample(); + sample3.setStableId(SAMPLE_ID3); + sample3.setCancerStudyIdentifier(STUDY_ID); + samples.add(sample3); + Sample sample4 = new Sample(); + sample4.setStableId(SAMPLE_ID4); + sample4.setCancerStudyIdentifier(STUDY_ID); + samples.add(sample4); + Sample sample5 = new Sample(); + sample5.setStableId(SAMPLE_ID5); + sample5.setCancerStudyIdentifier(STUDY_ID); + samples.add(sample5); + + when(sampleService.fetchSamples(studyIds, sampleIds, "ID")).thenReturn(samples); + + List molecularProfiles = new ArrayList<>(); + MolecularProfile molecularProfile1 = new MolecularProfile(); + molecularProfile1.setStableId(MOLECULAR_PROFILE_ID_1); + molecularProfile1.setCancerStudyIdentifier(STUDY_ID); + molecularProfiles.add(molecularProfile1); + + when(molecularProfileService.getMolecularProfilesInStudies(List.of(STUDY_ID), "SUMMARY")).thenReturn(molecularProfiles); + + List mutationList = new ArrayList<>(); + + Mutation mutation1 = new Mutation(); + mutation1.setSampleId(SAMPLE_ID1); + mutation1.setPatientId(PATIENT_ID1); + mutation1.setStudyId(STUDY_ID); + mutation1.setMutationType(MUTATION_TYPE_1); + mutationList.add(mutation1); + + Mutation mutation2 = new Mutation(); + mutation2.setSampleId(SAMPLE_ID2); + mutation2.setPatientId(PATIENT_ID1); + mutation2.setStudyId(STUDY_ID); + mutation2.setMutationType(MUTATION_TYPE_1); + mutationList.add(mutation2); + + Mutation mutation3 = new Mutation(); + mutation3.setSampleId(SAMPLE_ID3); + mutation3.setPatientId(PATIENT_ID2); + mutation3.setStudyId(STUDY_ID); + mutation3.setMutationType(MUTATION_TYPE_2); + mutationList.add(mutation3); + + Mutation mutation4 = new Mutation(); + mutation4.setSampleId(SAMPLE_ID4); + mutation4.setPatientId(PATIENT_ID2); + mutation4.setStudyId(STUDY_ID); + mutation4.setMutationType(MUTATION_TYPE_2); + mutationList.add(mutation4); + + Gene gene1 = new Gene(); + gene1.setEntrezGeneId(ENTREZ_GENE_ID_1); + gene1.setHugoGeneSymbol(HUGO_GENE_SYMBOL_1); + + when(geneService.fetchGenes(Arrays.asList(HUGO_GENE_SYMBOL_1), GeneIdType.HUGO_GENE_SYMBOL.name(), + Projection.SUMMARY.name())).thenReturn(Arrays.asList(gene1)); + when(mutationService.getMutationsInMultipleMolecularProfiles(anyList(), anyList(), + anyList(), anyString(), + isNull(), isNull(), isNull(), isNull())).thenReturn(mutationList); + + MutationDataFilter mutationDataFilter = new MutationDataFilter(); + mutationDataFilter.setHugoGeneSymbol(HUGO_GENE_SYMBOL_1); + mutationDataFilter.setProfileType(MOLECULAR_PROFILE_ID_1); + mutationDataFilter.setCategorization(MutationOption.MUTATED); + + DataFilterValue filterValue1 = new DataFilterValue(); + filterValue1.setValue("MUTATED"); + mutationDataFilter.setValues(List.of(List.of(filterValue1))); + studyViewFilter.setMutationDataFilters(Arrays.asList(mutationDataFilter)); + + List result1 = studyViewFilterApplier.apply(studyViewFilter); + // Return 4 samples since four mutations are MUTATED + Assert.assertEquals(4, result1.size()); + + DataFilterValue filterValue2 = new DataFilterValue(); + filterValue2.setValue(MUTATION_TYPE_1); + mutationDataFilter.setCategorization(MutationOption.MUTATION_TYPE); + mutationDataFilter.setValues(List.of(List.of(filterValue2))); + studyViewFilter.setMutationDataFilters(Collections.singletonList(mutationDataFilter)); + + // Return 2 samples since two mutations are MUTATION_TYPE_1 + List result2 = studyViewFilterApplier.apply(studyViewFilter); + Assert.assertEquals(2, result2.size()); + } + private DataFilterValue createDataFilterValue(String value) { DataFilterValue equalityFilter = new DataFilterValue(); equalityFilter.setValue(value); diff --git a/src/test/resources/cgds.sql b/src/test/resources/cgds.sql index 2971b3d1be6..67edccfbd69 100644 --- a/src/test/resources/cgds.sql +++ b/src/test/resources/cgds.sql @@ -45,8 +45,6 @@ DROP TABLE IF EXISTS `info`; DROP TABLE IF EXISTS `clinical_event_data`; DROP TABLE IF EXISTS `clinical_event`; -DROP TABLE IF EXISTS `pdb_uniprot_residue_mapping`; -DROP TABLE IF EXISTS `pdb_uniprot_alignment`; DROP TABLE IF EXISTS `cosmic_mutation`; DROP TABLE IF EXISTS `copy_number_seg_file`; DROP TABLE IF EXISTS `copy_number_seg`; diff --git a/src/test/resources/data.sql b/src/test/resources/data.sql index 4a92467d052..3e99783e959 100644 --- a/src/test/resources/data.sql +++ b/src/test/resources/data.sql @@ -4,8 +4,8 @@ INSERT INTO type_of_cancer (TYPE_OF_CANCER_ID,NAME,DEDICATED_COLOR,SHORT_NAME,PA INSERT INTO `reference_genome` VALUES (1, 'human', 'hg19', 'GRCh37', NULL, 'http://hgdownload.cse.ucsc.edu/goldenPath/hg19/bigZips', '2009-02-01 00:00:00'); INSERT INTO `reference_genome` VALUES (2, 'human', 'hg38', 'GRCh38', NULL, 'http://hgdownload.cse.ucsc.edu/goldenPath/hg38/bigZips', '2013-12-01 00:00:00'); -INSERT INTO cancer_study (CANCER_STUDY_ID,CANCER_STUDY_IDENTIFIER,TYPE_OF_CANCER_ID,NAME,DESCRIPTION,PUBLIC,PMID,CITATION,GROUPS,STATUS,IMPORT_DATE,REFERENCE_GENOME_ID) VALUES(1,'study_tcga_pub','brca','Breast Invasive Carcinoma (TCGA, Nature 2012)','The Cancer Genome Atlas (TCGA) Breast Invasive Carcinoma project. 825 cases.
Nature 2012. Raw data via the TCGA Data Portal.',1,'23000897,26451490','TCGA, Nature 2012, ...','SU2C-PI3K;PUBLIC;GDAC',0,'2011-12-18 13:17:17+00:00',1); -INSERT INTO cancer_study (CANCER_STUDY_ID,CANCER_STUDY_IDENTIFIER,TYPE_OF_CANCER_ID,NAME,DESCRIPTION,PUBLIC,PMID,CITATION,GROUPS,STATUS,IMPORT_DATE,REFERENCE_GENOME_ID) VALUES(2,'acc_tcga','acc','Adrenocortical Carcinoma (TCGA, Provisional)','TCGA Adrenocortical Carcinoma; raw data at the NCI.',1,'23000897','TCGA, Nature 2012','SU2C-PI3K;PUBLIC;GDAC',0,'2013-10-12 11:11:15+00:00',1); +INSERT INTO cancer_study (CANCER_STUDY_ID,CANCER_STUDY_IDENTIFIER,TYPE_OF_CANCER_ID,NAME,DESCRIPTION,PUBLIC,PMID,CITATION,GROUPS,STATUS,IMPORT_DATE,REFERENCE_GENOME_ID) VALUES(1,'study_tcga_pub','brca','Breast Invasive Carcinoma (TCGA, Nature 2012)','The Cancer Genome Atlas (TCGA) Breast Invasive Carcinoma project. 825 cases.
Nature 2012. Raw data via the TCGA Data Portal.',1,'23000897,26451490','TCGA, Nature 2012, ...','SU2C-PI3K;GDAC',0,'2011-12-18 13:17:17+00:00',1); +INSERT INTO cancer_study (CANCER_STUDY_ID,CANCER_STUDY_IDENTIFIER,TYPE_OF_CANCER_ID,NAME,DESCRIPTION,PUBLIC,PMID,CITATION,GROUPS,STATUS,IMPORT_DATE,REFERENCE_GENOME_ID) VALUES(2,'acc_tcga','acc','Adrenocortical Carcinoma (TCGA, Provisional)','TCGA Adrenocortical Carcinoma; raw data at the NCI.',1,'23000897','TCGA, Nature 2012','SU2C-PI3K;GDAC',0,'2013-10-12 11:11:15+00:00',1); INSERT INTO cancer_study_tags (CANCER_STUDY_ID,TAGS) VALUES(1,'{"Analyst": {"Name": "Jack", "Email": "jack@something.com"}, "Load id": 35}'); INSERT INTO cancer_study_tags (CANCER_STUDY_ID,TAGS) VALUES(2,'{"Load id": 36}'); diff --git a/src/test/resources/maven.properties b/src/test/resources/maven.properties index 11a8024da83..9ef36016da2 100644 --- a/src/test/resources/maven.properties +++ b/src/test/resources/maven.properties @@ -1,2 +1,3 @@ portal.version=test_portal_version -db.version=test_db_version \ No newline at end of file +db.version=test_db_version +app.version=test_app_version diff --git a/src/test/resources/security/keycloak-configuration-generated.json b/src/test/resources/security/keycloak-configuration-generated.json index 2f4d513791a..6aa760d1f49 100644 --- a/src/test/resources/security/keycloak-configuration-generated.json +++ b/src/test/resources/security/keycloak-configuration-generated.json @@ -282,16 +282,16 @@ { "id": "4b5c2aa6-bc44-458d-ac1f-1a2166520f4d", "clientId": "cbioportal", - "adminUrl": "http://host.testcontainers.internal:8080/saml", + "adminUrl": "", "surrogateAuthRequired": false, "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", "redirectUris": [ - "http://host.testcontainers.internal:8080/*" + "http://localhost:8080/*" ], "webOrigins": [ - "http://host.testcontainers.internal:8080" + "http://localhost:8080" ], "notBefore": 0, "bearerOnly": false, @@ -306,14 +306,14 @@ "attributes": { "saml.assertion.signature": "false", "saml.force.post.binding": "false", - "saml_single_logout_service_url_post": "http://host.testcontainers.internal:8080/logout/saml2/slo", + "saml_single_logout_service_url_post": "http://localhost:8080/login?logout_success", "signing.private.key": "MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDJTDNHzHv19kM4tVLOIjpR/vez4QJk70PMbghQBdCp1Er1yU8GkQRMx0QtumQB2ML1p2f63EEd7WsAPMEVYNQv6MHJDhAIDt+npWmYrGl3PrkVA3GNzZcD+GQEMZdGcECvfocOy2tB6iMOhdnFqu4L/QfFG2yJ+CpimpijvW78cJ35oYmOTnD7R9LBAJQuBlQDpOvB+I/dFeCiNKw61HQy0nMf6oe0pBy4E7bImQ0HY/soxBnzbvPUzbBvnhb2d97l3wn6ElUMrZuQSyI+OyVgBMyv9gcgV4Wq16oEuNkWFIdY2j8GeiDlqy9KJAttgLXBjGua2lRML0a+nrfF1VbBLgyzAZZP2IS/P3QYcSE2GbPWiWXjov2vF63/VnARzQhPhuLGilWp1Nxqr0HztgSiAyx0D3wqEBic0ERAQDVuHQZdjPd7RJaJ6MBnZH9mMVQOrjspIP5Sc6Z7omou26LPTjWNwmNWnfrq1sU8ADg4Uj09PWYcuWhPKxe6K9Zm4PLGXA0fR/fCVPDKaJPXIC7FGzDDdh/uSb9OURlgHwe319FCdvm1k7xD6tEfsyORjWJFoYvyT015j9LdBuO5fwt40EPCzNezqWCaimES7u3Puyg+4mbnRDh1UuouHOHVZ4jWySrrEktI0l6JkxrqdT2ilw7ICtmFx2fsjO9qso4tGwIDAQABAoICAFT7iprBRYQtl2uVgYPtB1oenkyerfgW2zSvL2s5SUKpkYv6lRZcmsgfSDVV/2qYLJaxOkC6Q/NyjD3paEqyOmKPjWBoQ3RjcyC/wLjn8Q6auGCat5H6Pcs7Tl5G4WqncWelrzcbwght5Kb481t0MlN1W5ZnYYdN8fb29YILM5P3p3oALKabjy9Gvz8kE2rq2QVA1xdo7LOVzOQuAJhFoVjjaB8NUIV+03ETQZOmqc149EvdnmcbbG1m+RnmUCN1r/C0HO4qVyWnFYnxbl9/cOP8or2WzKNmz9O0gN7Fe0DLIejtGraNUN4lSy2t0fVE5Xb05WjWy8fuHZvUPhmTW7Ap1WBGPpfjsbp+e5kx10rwWrWlKgcF7tNUUN9v0vJWKoF2Lr0+C5dphIz6LEZO7lThjh3oOXjN4jbtoZbd9tZ614dwUTPlllgQiHhNYeAK13REpX/Jx6Dgn6w5s2g+e7++4U93FMNkYjzArXAYhQd6CisFH32fr9Cc1WuUwhe6E7fABcynmMfpZhkwcCTPT+Qb1CGsMvDUdETY1J4pL+Wlgwxidd0IKyOgIu6SpQ6JEeghJzl4XOnCWlJIlO8rts7oy/0PaPWanl5rCUeeK5g32yv85bvUNJnkZ2YGBPM8c8wqsL91A+30WX1tE65JzqNI3LGDLD/WGzCYMMR1Q0/hAoIBAQD/R6bpASFPhjgDJwqjrnEhd92I5q97f+fkGqbEsVVaZQrkw2O74EyFjMWwNNG1VzYeOAAjbRkv0mXg6v6Djbuz5omkjF+qwyxXmgpYe8aJ5sU34BWVoIJsXkdCkAC49q2KsoiYT+fFw3IjlpVcIvfkV7YnVeveJ47Z9+xjrBSkKEIfZhBsd57wV+0LZ42Q/ULuPPnTlXQ77nqtBu6DusOjO1cYod5M4k0JlJwqNn39rwxCgIr5CI1UqsVJHsZz+lGQsu5ClC02V8HOTh8UjJtAcVslo+i6gLOHxB4zvDRzAXnsFIrrukqp4Bz4djoE8np/mWDtSpanoBuF84/prpTvAoIBAQDJ3ZDIBZlmTPhDUEbb6jG/AEsqeDUBgG5igLHxUg3StWgVL4cbNcRyeKD5VxMrO7pIfBm02GRqCRpmxqeOadlBgTe52oG5MIrEVIHt1KT6E1LAP7jD0ABvf3P7e9wtXlDRAsIGLIDIsb4toQFotUi6ayl07zB0+vJ1tWU+qB1ZJWWYRpDmCQG6/1vz3dBkjRPGzT79zXSxbY2beNxKYIsL1LVR0BeLd4Tbn8mLL+fxjRep4qGO1fu+w62RqQvClSUIBgZJlpEcuhRFbAL+zhqmuaq0MkcF65bHQCs/iddF9dUpNYSzUnR6N7fb9MkJZX9ww7tHLbefu+lGVTD/8mKVAoIBAQCw4JOsxGSxNj1fKdD8YqTuXKA5+CTEvHYPHcxJYtnR/UrUAPH8vkgnDMf49FANhvTvcTvfT/twoCaI9ioNOspAt07NnZm3tu3lcM0UTAbfi+9AbNpnx0Q3FAfp/d8SSZErFdMBPfRImchfEjpBEdWS+Jc0oBsC3YPkUR0QXq4ao+5U1SIyFZwhybpr+X8kY+bZLZSoXtifofiMJM5kpaZiVn5dieJ+gRqBtd+SfBlGCeDDv08LiDps3Lo/lLxKpbmYOfJOXV8KVTnq2UQ9t8LmnuRZqz1Y5E4AlwmaLSBmQzKYOg+bj4OmOqu4GCrRPLVV7g8zu0exs4T+hilD7/wvAoIBAE3KMyvRdI7GpHkUK2o9spPfIhgooIyGmIMfAvNy4l7Lh2N6oD7tFlnigG31jy5+4sdiA2n8ZZ2zCliGvzUTNySWDgpx2MGroh4MTtF+u2CfJ6lsJOBYfIJ7BA/qaCuXh98zh99nMO2mCRp+TBO0oGUuPJiSQAMkXWDc2TovALhEwATRVK9A00jjdOTiGpdVAkT+/QJDNW/WPtal2YZT8+FIQ+NWJGybTzhvN/SKLoCYFYFjE0z+yvd1YqKaGS0P2mhgIfYjrqH6Vyt1dyYH+J89Nzofkd0HL2BzKvdeP/X2yQELXarY4IfkhtadWwdi9JxY4QeJ55QHjtqKo8pN9o0CggEAWg3kw1pLAsEtRO+5w+TLMAx8JXxhbIG2ITtGHU/eCd7YO2Ax+LHd8UjjJI59QXpmytfLd6czy8bvYaAW/LtbOPYwdWGVetWMjim5KceAz64koHcBsVK1Su4i72MWagbEcwfAlZbwrIEcccZHW0/wTvwtZzllafCJhplN0+Et6vPLG00v7+x9krZOT9zGAFbt79J/kNrwZ1BRNJIl+UPM1K18AKA4xFEmClqctejNSLLubPrwC0Vdokm8tYDRBI6r+M8w6wcHW9NXYQzQ27UZKAqrtyFXJ1coQQpwHCYJi7vztacjMOLEPuKvKNSWUanv0GBYB9lnaY3wS/ncYpn8MQ==", "saml.server.signature": "true", "saml.signing.certificate": "MIIFazCCA1OgAwIBAgIUVMt2XXqYekaunKy/fhcJNQzJ0uQwDQYJKoZIhvcNAQELBQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTExMTkxMzUyMzFaFw0yMjExMTkxMzUyMzFaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJTDNHzHv19kM4tVLOIjpR/vez4QJk70PMbghQBdCp1Er1yU8GkQRMx0QtumQB2ML1p2f63EEd7WsAPMEVYNQv6MHJDhAIDt+npWmYrGl3PrkVA3GNzZcD+GQEMZdGcECvfocOy2tB6iMOhdnFqu4L/QfFG2yJ+CpimpijvW78cJ35oYmOTnD7R9LBAJQuBlQDpOvB+I/dFeCiNKw61HQy0nMf6oe0pBy4E7bImQ0HY/soxBnzbvPUzbBvnhb2d97l3wn6ElUMrZuQSyI+OyVgBMyv9gcgV4Wq16oEuNkWFIdY2j8GeiDlqy9KJAttgLXBjGua2lRML0a+nrfF1VbBLgyzAZZP2IS/P3QYcSE2GbPWiWXjov2vF63/VnARzQhPhuLGilWp1Nxqr0HztgSiAyx0D3wqEBic0ERAQDVuHQZdjPd7RJaJ6MBnZH9mMVQOrjspIP5Sc6Z7omou26LPTjWNwmNWnfrq1sU8ADg4Uj09PWYcuWhPKxe6K9Zm4PLGXA0fR/fCVPDKaJPXIC7FGzDDdh/uSb9OURlgHwe319FCdvm1k7xD6tEfsyORjWJFoYvyT015j9LdBuO5fwt40EPCzNezqWCaimES7u3Puyg+4mbnRDh1UuouHOHVZ4jWySrrEktI0l6JkxrqdT2ilw7ICtmFx2fsjO9qso4tGwIDAQABo1MwUTAdBgNVHQ4EFgQU0JL52xvzhG/48H01Rxac3MOgZYEwHwYDVR0jBBgwFoAU0JL52xvzhG/48H01Rxac3MOgZYEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAYYbj4v37eUTo9mtWgtZ2hHjWtdScPlZGxZanPZZpAcN8JR07ps/wow68rQMOZR9hFS6c2+izbn3HkR3OwCK9sZeuWzrLVPUBSiXxEbRkpK/pXAd/Irat+f1ylA3j3J4VyDJymqiuIBOE9kzGWpbMdyqlHdH5XG/giLEOY66p6k5QrtKDXKzfQ7BBzO1WTe1BkWp7HerEKqM7mRSA4pRT5J7UAGn4gHOU39bnOHZPhko/rFagI2iO8T3fSBL+IWx76ROoG3DUnaZmDIuMxzeEZD7G8aPWOJCP0/mnBrAQhsEUg0bcsRa6qzWFigY4oWjxOSc2aQMRSjxrVf59Geplyhh8AY0yI49uhJJc6SztwuiX9fksCm1/Z9YZeeJr/oOkBduGpX6BQbPA7N2yKg5APdn8DVIHFALijwobz+94+d6uv4+ihlQ8jBgbo1kwMZps+BAVOODgX3RpFKmqcyX9bjWaapw+XE1U8Rtt3mcgN9qchvcIqcnGZ1PfaY1ultvAzUa4TCECiYRXSOXT4iAXv+M1i2XisuThtw7dC9HMY1D/0oA/cRxwknLsuKRRGJWbUN/Ts4GMjLmvKejQOWfS+/wHS9kQdPKS3BKZYQgqli4OG1xRErykL6SRWTKJA3+VNditbHFkJuL9dGZLu0Dmaww6K1SSnYai77uTTPdOHoc=", "saml.artifact.binding.identifier": "eY7tz0hmV0aMmBtL/oU7BOy5kUY=", "saml.signature.algorithm": "RSA_SHA256", "saml_force_name_id_format": "true", - "saml.client.signature": "true", + "saml.client.signature": "false", "saml.authnstatement": "true", "saml_name_id_format": "email", "saml_signature_canonicalization_method": "http://www.w3.org/2001/10/xml-exc-c14n#" @@ -361,10 +361,10 @@ "clientAuthenticatorType": "client-secret", "secret": "client_secret", "redirectUris": [ - "http://host.testcontainers.internal:8080/*" + "http://localhost:8080/*" ], "webOrigins": [ - "http://host.testcontainers.internal:8080" + "http://localhost:8080" ], "notBefore": 0, "bearerOnly": false, @@ -396,11 +396,11 @@ } ], "defaultClientScopes": [ - "email" + "email", + "roles" ], "optionalClientScopes": [ - "offline_access", - "roles" + "offline_access" ] }, { @@ -1891,6 +1891,15 @@ ] } ], + "roles": { + "client": { + "cbioportal": [ + { + "name": "study_tcga_pub" + } + ] + } + }, "groups": [ { "name": "PUBLIC_STUDIES", diff --git a/src/test/resources/seed_mini.sql b/src/test/resources/seed_mini.sql index a4b224d9294..01c57b3f61f 100644 --- a/src/test/resources/seed_mini.sql +++ b/src/test/resources/seed_mini.sql @@ -38,26 +38,14 @@ SET SESSION sql_mode = 'ANSI_QUOTES'; DELETE FROM structural_variant; DELETE FROM clinical_event_data; DELETE FROM clinical_event; -DELETE FROM pdb_uniprot_residue_mapping; -DELETE FROM pdb_uniprot_alignment; DELETE FROM cosmic_mutation; DELETE FROM copy_number_seg_file; DELETE FROM copy_number_seg; DELETE FROM sample_cna_event; DELETE FROM cna_event; -DELETE FROM drug_interaction; -DELETE FROM drug; -DELETE FROM pfam_graphics; -DELETE FROM text_cache; DELETE FROM gistic_to_gene; DELETE FROM gistic; -DELETE FROM sanger_cancer_census; -DELETE FROM protein_array_cancer_study; -DELETE FROM protein_array_data; -DELETE FROM protein_array_target; -DELETE FROM protein_array_info; DELETE FROM mut_sig; -DELETE FROM interaction; DELETE FROM clinical_attribute_meta; DELETE FROM mutation; DELETE FROM mutation_event; @@ -67,7 +55,6 @@ DELETE FROM gene_panel_list; DELETE FROM genetic_profile_samples; DELETE FROM genetic_alteration; DELETE FROM genetic_profile; -DELETE FROM uniprot_id_mapping; DELETE FROM gene_alias; DELETE FROM gene; DELETE FROM clinical_sample; @@ -101,7 +88,11 @@ INSERT INTO `reference_genome` VALUES (2,'human','hg38','GRCh38',3049315783,'htt -- cancer_study INSERT INTO "cancer_study" ("CANCER_STUDY_ID","CANCER_STUDY_IDENTIFIER","TYPE_OF_CANCER_ID","NAME","DESCRIPTION","PUBLIC","PMID","CITATION","GROUPS","REFERENCE_GENOME_ID") -VALUES (1,'study_tcga_pub','brca','Breast Invasive Carcinoma (TCGA,Nature 2012)','The Cancer Genome Atlas (TCGA) Breast Invasive Carcinoma project. 825 cases.
Nature 2012. Raw data via the TCGA Data Portal.',1,'23000897,26451490','TCGA,Nature 2012,...','SU2C-PI3K;PUBLIC;GDAC',1); +VALUES (1,'study_tcga_pub','brca','Breast Invasive Carcinoma (TCGA,Nature 2012)','The Cancer Genome Atlas (TCGA) Breast Invasive Carcinoma project. 825 cases.
Nature 2012. Raw data via the TCGA Data Portal.',1,'23000897,26451490','TCGA,Nature 2012,...','SU2C-PI3K;GDAC',1); + +INSERT INTO "cancer_study" ("CANCER_STUDY_ID","CANCER_STUDY_IDENTIFIER","TYPE_OF_CANCER_ID","NAME","DESCRIPTION","PUBLIC","PMID","CITATION","GROUPS","REFERENCE_GENOME_ID") +VALUES(2,'acc_tcga','acc','Adrenocortical Carcinoma (TCGA, Provisional)','TCGA Adrenocortical Carcinoma; raw data at the NCI.',1,'23000897','TCGA, Nature 2012','SU2C-PI3K;GDAC',1); + -- gene as genetic_entity INSERT INTO "genetic_entity" ("ENTITY_TYPE") VALUES ('GENE'); @@ -316,14 +307,14 @@ INSERT INTO "gene_alias" ("ENTREZ_GENE_ID","GENE_ALIAS") VALUES (2261,'ACH'); INSERT INTO "gene_alias" ("ENTREZ_GENE_ID","GENE_ALIAS") VALUES (2261,'CEK2'); INSERT INTO "gene_alias" ("ENTREZ_GENE_ID","GENE_ALIAS") VALUES (2261,'CD333'); -INSERT INTO reference_genome_gene (ENTREZ_GENE_ID,CYTOBAND,EXONIC_LENGTH,START,END,CHR,REFERENCE_GENOME_ID) VALUES(207,'14q32.33',10838,105235686,105262088,14,1); -INSERT INTO reference_genome_gene (ENTREZ_GENE_ID,CYTOBAND,EXONIC_LENGTH,START,END,CHR,REFERENCE_GENOME_ID) VALUES(207,'14q32.33',11162,104769349,104795751,14,2); -INSERT INTO reference_genome_gene (ENTREZ_GENE_ID,CYTOBAND,EXONIC_LENGTH,START,END,CHR,REFERENCE_GENOME_ID) VALUES(208,'19q13.2',15035,40736224,40791443,19,1); -INSERT INTO reference_genome_gene (ENTREZ_GENE_ID,CYTOBAND,EXONIC_LENGTH,START,END,CHR,REFERENCE_GENOME_ID) VALUES(208,'19q13.2',15035,40230317,40285536,19,2); -INSERT INTO reference_genome_gene (ENTREZ_GENE_ID,CYTOBAND,EXONIC_LENGTH,START,END,CHR,REFERENCE_GENOME_ID) VALUES(51259,'11q12.2',2364,61159159,61166335,11,1); -INSERT INTO reference_genome_gene (ENTREZ_GENE_ID,CYTOBAND,EXONIC_LENGTH,START,END,CHR,REFERENCE_GENOME_ID) VALUES(51259,'11q12.2',2364,61391687,61398863,11,2); -INSERT INTO reference_genome_gene (ENTREZ_GENE_ID,CYTOBAND,EXONIC_LENGTH,START,END,CHR,REFERENCE_GENOME_ID) VALUES(282770,'11q12.1',2814,55734975,55735990,11,1); -INSERT INTO reference_genome_gene (ENTREZ_GENE_ID,CYTOBAND,EXONIC_LENGTH,START,END,CHR,REFERENCE_GENOME_ID) VALUES(282770,'11q12.1',2814,55967558,55968463,11,2); +INSERT INTO reference_genome_gene (ENTREZ_GENE_ID,CYTOBAND,START,END,CHR,REFERENCE_GENOME_ID) VALUES(207,'14q32.33',105235686,105262088,14,1); +INSERT INTO reference_genome_gene (ENTREZ_GENE_ID,CYTOBAND,START,END,CHR,REFERENCE_GENOME_ID) VALUES(207,'14q32.33',104769349,104795751,14,2); +INSERT INTO reference_genome_gene (ENTREZ_GENE_ID,CYTOBAND,START,END,CHR,REFERENCE_GENOME_ID) VALUES(208,'19q13.2',40736224,40791443,19,1); +INSERT INTO reference_genome_gene (ENTREZ_GENE_ID,CYTOBAND,START,END,CHR,REFERENCE_GENOME_ID) VALUES(208,'19q13.2',40230317,40285536,19,2); +INSERT INTO reference_genome_gene (ENTREZ_GENE_ID,CYTOBAND,START,END,CHR,REFERENCE_GENOME_ID) VALUES(51259,'11q12.2',61159159,61166335,11,1); +INSERT INTO reference_genome_gene (ENTREZ_GENE_ID,CYTOBAND,START,END,CHR,REFERENCE_GENOME_ID) VALUES(51259,'11q12.2',61391687,61398863,11,2); +INSERT INTO reference_genome_gene (ENTREZ_GENE_ID,CYTOBAND,START,END,CHR,REFERENCE_GENOME_ID) VALUES(282770,'11q12.1',55734975,55735990,11,1); +INSERT INTO reference_genome_gene (ENTREZ_GENE_ID,CYTOBAND,START,END,CHR,REFERENCE_GENOME_ID) VALUES(282770,'11q12.1',55967558,55968463,11,2); INSERT INTO "genetic_profile" ("GENETIC_PROFILE_ID","STABLE_ID","CANCER_STUDY_ID","GENETIC_ALTERATION_TYPE","DATATYPE","NAME","DESCRIPTION","SHOW_PROFILE_IN_ANALYSIS_TAB") VALUES (2,'study_tcga_pub_gistic',1,'COPY_NUMBER_ALTERATION','DISCRETE','Putative copy-number alterations from GISTIC','Putative copy-number from GISTIC 2.0. Values: -2 = homozygous deletion; -1 = hemizygous deletion; 0 = neutral / no change; 1 = gain; 2 = high level amplification.','1'); INSERT INTO "genetic_profile" ("GENETIC_PROFILE_ID","STABLE_ID","CANCER_STUDY_ID","GENETIC_ALTERATION_TYPE","DATATYPE","NAME","DESCRIPTION","SHOW_PROFILE_IN_ANALYSIS_TAB") VALUES (3,'study_tcga_pub_mrna',1,'MRNA_EXPRESSION','Z-SCORE','mRNA expression (microarray)','Expression levels (Agilent microarray).','0'); @@ -397,10 +388,10 @@ INSERT INTO "patient" ("INTERNAL_ID","STABLE_ID","CANCER_STUDY_ID") VALUES (11,' INSERT INTO "patient" ("INTERNAL_ID","STABLE_ID","CANCER_STUDY_ID") VALUES (12,'TCGA-A1-A0SO',1); INSERT INTO "patient" ("INTERNAL_ID","STABLE_ID","CANCER_STUDY_ID") VALUES (13,'TCGA-A1-A0SP',1); INSERT INTO "patient" ("INTERNAL_ID","STABLE_ID","CANCER_STUDY_ID") VALUES (14,'TCGA-A1-A0SQ',1); -INSERT INTO "patient" ("INTERNAL_ID","STABLE_ID","CANCER_STUDY_ID") VALUES (15,'TCGA-XX-0800',1); -INSERT INTO "patient" ("INTERNAL_ID","STABLE_ID","CANCER_STUDY_ID") VALUES (16,'TCGA-XX-0900',1); -INSERT INTO "patient" ("INTERNAL_ID","STABLE_ID","CANCER_STUDY_ID") VALUES (17,'TCGA-AA-3664',1); -INSERT INTO "patient" ("INTERNAL_ID","STABLE_ID","CANCER_STUDY_ID") VALUES (18,'TCGA-AA-3665',1); +INSERT INTO "patient" ("INTERNAL_ID","STABLE_ID","CANCER_STUDY_ID") VALUES (15,'TCGA-XX-0800',2); +INSERT INTO "patient" ("INTERNAL_ID","STABLE_ID","CANCER_STUDY_ID") VALUES (16,'TCGA-XX-0900',2); +INSERT INTO "patient" ("INTERNAL_ID","STABLE_ID","CANCER_STUDY_ID") VALUES (17,'TCGA-AA-3664',2); +INSERT INTO "patient" ("INTERNAL_ID","STABLE_ID","CANCER_STUDY_ID") VALUES (18,'TCGA-AA-3665',2); -- sample INSERT INTO "sample" ("INTERNAL_ID","STABLE_ID","SAMPLE_TYPE","PATIENT_ID") VALUES (1,'TCGA-A1-A0SB-01','Primary Solid Tumor',1); @@ -424,9 +415,9 @@ INSERT INTO "sample" ("INTERNAL_ID","STABLE_ID","SAMPLE_TYPE","PATIENT_ID") VALU INSERT INTO "sample" ("INTERNAL_ID","STABLE_ID","SAMPLE_TYPE","PATIENT_ID") VALUES (19,'TCGA-A1-A0SB-02','Primary Solid Tumor',1); -- mutation_event -INSERT INTO "mutation_event" ("MUTATION_EVENT_ID","ENTREZ_GENE_ID","CHR","START_POSITION","END_POSITION","REFERENCE_ALLELE","TUMOR_SEQ_ALLELE","PROTEIN_CHANGE","MUTATION_TYPE","FUNCTIONAL_IMPACT_SCORE","FIS_VALUE","LINK_XVAR","LINK_PDB","LINK_MSA","NCBI_BUILD","STRAND","VARIANT_TYPE","DB_SNP_RS","DB_SNP_VAL_STATUS","ONCOTATOR_DBSNP_RS","ONCOTATOR_REFSEQ_MRNA_ID","ONCOTATOR_CODON_CHANGE","ONCOTATOR_UNIPROT_ENTRY_NAME","ONCOTATOR_UNIPROT_ACCESSION","ONCOTATOR_PROTEIN_POS_START","ONCOTATOR_PROTEIN_POS_END","CANONICAL_TRANSCRIPT","KEYWORD") VALUES (2038,672,'17',41244748,41244748,'G','A','Q934*','Nonsense_Mutation','NA',0,'getma.org/?cm=var&var=hg19,17,41244748,G,A&fts=all','NA','NA','37','+','SNP','rs80357223','unknown','rs80357223','NM_007294','c.(2800-2802)CAG>TAG','BRCA1_HUMAN','P38398',934,934,1,'BRCA1 truncating'); -INSERT INTO "mutation_event" ("MUTATION_EVENT_ID","ENTREZ_GENE_ID","CHR","START_POSITION","END_POSITION","REFERENCE_ALLELE","TUMOR_SEQ_ALLELE","PROTEIN_CHANGE","MUTATION_TYPE","FUNCTIONAL_IMPACT_SCORE","FIS_VALUE","LINK_XVAR","LINK_PDB","LINK_MSA","NCBI_BUILD","STRAND","VARIANT_TYPE","DB_SNP_RS","DB_SNP_VAL_STATUS","ONCOTATOR_DBSNP_RS","ONCOTATOR_REFSEQ_MRNA_ID","ONCOTATOR_CODON_CHANGE","ONCOTATOR_UNIPROT_ENTRY_NAME","ONCOTATOR_UNIPROT_ACCESSION","ONCOTATOR_PROTEIN_POS_START","ONCOTATOR_PROTEIN_POS_END","CANONICAL_TRANSCRIPT","KEYWORD") VALUES (22604,672,'17',41258504,41258504,'A','C','C61G','Missense_Mutation','H',4.355,'getma.org/?cm=var&var=hg19,17,41258504,A,C&fts=all','getma.org/pdb.php?prot=BRCA1_HUMAN&from=24&to=64&var=C61G','getma.org/?cm=msa&ty=f&p=BRCA1_HUMAN&rb=24&re=64&var=C61G','37','+','SNP','rs28897672','byCluster','rs28897672','NM_007294','c.(181-183)TGT>GGT','BRCA1_HUMAN','P38398',61,61,1,'BRCA1 C61 missense'); -INSERT INTO "mutation_event" ("MUTATION_EVENT_ID","ENTREZ_GENE_ID","CHR","START_POSITION","END_POSITION","REFERENCE_ALLELE","TUMOR_SEQ_ALLELE","PROTEIN_CHANGE","MUTATION_TYPE","FUNCTIONAL_IMPACT_SCORE","FIS_VALUE","LINK_XVAR","LINK_PDB","LINK_MSA","NCBI_BUILD","STRAND","VARIANT_TYPE","DB_SNP_RS","DB_SNP_VAL_STATUS","ONCOTATOR_DBSNP_RS","ONCOTATOR_REFSEQ_MRNA_ID","ONCOTATOR_CODON_CHANGE","ONCOTATOR_UNIPROT_ENTRY_NAME","ONCOTATOR_UNIPROT_ACCESSION","ONCOTATOR_PROTEIN_POS_START","ONCOTATOR_PROTEIN_POS_END","CANONICAL_TRANSCRIPT","KEYWORD") VALUES (2039,672,'17',41276033,41276033,'C','T','C27_splice','Splice_Site','NA',1.4013e-45,'NA','NA','NA','37','+','SNP','rs80358010','byCluster','rs80358010','NM_007294','c.e2+1','NA','NA',-1,-1,1,'BRCA1 truncating'); +INSERT INTO "mutation_event" ("MUTATION_EVENT_ID","ENTREZ_GENE_ID","CHR","START_POSITION","END_POSITION","REFERENCE_ALLELE","TUMOR_SEQ_ALLELE","PROTEIN_CHANGE","MUTATION_TYPE","NCBI_BUILD","STRAND","VARIANT_TYPE","DB_SNP_RS","DB_SNP_VAL_STATUS","CANONICAL_TRANSCRIPT","KEYWORD") VALUES (2038,672,'17',41244748,41244748,'G','A','Q934*','Nonsense_Mutation','37','+','SNP','rs80357223','unknown',1,'BRCA1 truncating'); +INSERT INTO "mutation_event" ("MUTATION_EVENT_ID","ENTREZ_GENE_ID","CHR","START_POSITION","END_POSITION","REFERENCE_ALLELE","TUMOR_SEQ_ALLELE","PROTEIN_CHANGE","MUTATION_TYPE","NCBI_BUILD","STRAND","VARIANT_TYPE","DB_SNP_RS","DB_SNP_VAL_STATUS","CANONICAL_TRANSCRIPT","KEYWORD") VALUES (22604,672,'17',41258504,41258504,'A','C','C61G','Missense_Mutation','37','+','SNP','rs28897672','byCluster',1,'BRCA1 C61 missense'); +INSERT INTO "mutation_event" ("MUTATION_EVENT_ID","ENTREZ_GENE_ID","CHR","START_POSITION","END_POSITION","REFERENCE_ALLELE","TUMOR_SEQ_ALLELE","PROTEIN_CHANGE","MUTATION_TYPE","NCBI_BUILD","STRAND","VARIANT_TYPE","DB_SNP_RS","DB_SNP_VAL_STATUS","CANONICAL_TRANSCRIPT","KEYWORD") VALUES (2039,672,'17',41276033,41276033,'C','T','C27_splice','Splice_Site','37','+','SNP','rs80358010','byCluster',1,'BRCA1 truncating'); -- mutation INSERT INTO "mutation" ("MUTATION_EVENT_ID","GENETIC_PROFILE_ID","SAMPLE_ID","ENTREZ_GENE_ID","CENTER","SEQUENCER","MUTATION_STATUS","VALIDATION_STATUS","TUMOR_SEQ_ALLELE1","TUMOR_SEQ_ALLELE2","MATCHED_NORM_SAMPLE_BARCODE","MATCH_NORM_SEQ_ALLELE1","MATCH_NORM_SEQ_ALLELE2","TUMOR_VALIDATION_ALLELE1","TUMOR_VALIDATION_ALLELE2","MATCH_NORM_VALIDATION_ALLELE1","MATCH_NORM_VALIDATION_ALLELE2","VERIFICATION_STATUS","SEQUENCING_PHASE","SEQUENCE_SOURCE","VALIDATION_METHOD","SCORE","BAM_FILE","TUMOR_ALT_COUNT","TUMOR_REF_COUNT","NORMAL_ALT_COUNT","NORMAL_REF_COUNT") VALUES (2038,6,6,672,'genome.wustl.edu','IlluminaGAIIx','Germline','Unknown','G','A','TCGA-A1-A0SH-10A-03D-A099-09','G','A','NA','NA','NA','NA','Unknown','Phase_IV','Capture','NA','1','dbGAP',-1,-1,-1,-1); @@ -442,6 +433,7 @@ INSERT INTO "sample_list" ("LIST_ID","STABLE_ID","CATEGORY","CANCER_STUDY_ID","N INSERT INTO "sample_list" ("LIST_ID","STABLE_ID","CATEGORY","CANCER_STUDY_ID","NAME","DESCRIPTION") VALUES (6,'study_tcga_pub_methylation_hm27','other',1,'Tumors with methylation data','All samples with methylation (HM27) data (311 samples)'); INSERT INTO "sample_list" ("LIST_ID","STABLE_ID","CATEGORY","CANCER_STUDY_ID","NAME","DESCRIPTION") VALUES (7,'study_tcga_pub_mrna','other',1,'Tumors with mRNA data (Agilent microarray)','All samples with mRNA expression data (526 samples)'); INSERT INTO "sample_list" ("LIST_ID","STABLE_ID","CATEGORY","CANCER_STUDY_ID","NAME","DESCRIPTION") VALUES (8,'study_tcga_pub_sequenced','other',1,'Sequenced Tumors','All sequenced samples (507 samples)'); +INSERT INTO sample_list (LIST_ID,STABLE_ID,CATEGORY,CANCER_STUDY_ID,NAME,DESCRIPTION) VALUES (14,'acc_tcga_all','other',2,'All Tumors','All tumor samples'); -- sample_list_list INSERT INTO "sample_list_list" ("LIST_ID","SAMPLE_ID") VALUES (1,1); @@ -516,6 +508,8 @@ INSERT INTO "sample_list_list" ("LIST_ID","SAMPLE_ID") VALUES (8,8); INSERT INTO "sample_list_list" ("LIST_ID","SAMPLE_ID") VALUES (8,9); INSERT INTO "sample_list_list" ("LIST_ID","SAMPLE_ID") VALUES (8,10); INSERT INTO "sample_list_list" ("LIST_ID","SAMPLE_ID") VALUES (8,12); +INSERT INTO sample_list_list (LIST_ID,SAMPLE_ID) VALUES (14,15); + -- sample_cna_event INSERT INTO "sample_cna_event" ("CNA_EVENT_ID","SAMPLE_ID","GENETIC_PROFILE_ID") VALUES (2774,4,2); @@ -582,32 +576,6 @@ INSERT INTO "sample_profile" ("SAMPLE_ID","GENETIC_PROFILE_ID","PANEL_ID") VALUE INSERT INTO "sample_profile" ("SAMPLE_ID","GENETIC_PROFILE_ID","PANEL_ID") VALUES (14,2,NULL); INSERT INTO "sample_profile" ("SAMPLE_ID","GENETIC_PROFILE_ID","PANEL_ID") VALUES (14,4,NULL); --- uniprot_id_mapping -INSERT INTO "uniprot_id_mapping" ("UNIPROT_ACC","UNIPROT_ID","ENTREZ_GENE_ID") VALUES ('P31749','AKT1_HUMAN',207); -INSERT INTO "uniprot_id_mapping" ("UNIPROT_ACC","UNIPROT_ID","ENTREZ_GENE_ID") VALUES ('P31751','AKT2_HUMAN',208); -INSERT INTO "uniprot_id_mapping" ("UNIPROT_ACC","UNIPROT_ID","ENTREZ_GENE_ID") VALUES ('Q9Y243','AKT3_HUMAN',10000); -INSERT INTO "uniprot_id_mapping" ("UNIPROT_ACC","UNIPROT_ID","ENTREZ_GENE_ID") VALUES ('P10398','ARAF_HUMAN',369); -INSERT INTO "uniprot_id_mapping" ("UNIPROT_ACC","UNIPROT_ID","ENTREZ_GENE_ID") VALUES ('Q13315','ATM_HUMAN',472); -INSERT INTO "uniprot_id_mapping" ("UNIPROT_ACC","UNIPROT_ID","ENTREZ_GENE_ID") VALUES ('P15056','BRAF_HUMAN',673); -INSERT INTO "uniprot_id_mapping" ("UNIPROT_ACC","UNIPROT_ID","ENTREZ_GENE_ID") VALUES ('P38398','BRCA1_HUMAN',672); -INSERT INTO "uniprot_id_mapping" ("UNIPROT_ACC","UNIPROT_ID","ENTREZ_GENE_ID") VALUES ('P51587','BRCA2_HUMAN',675); -INSERT INTO "uniprot_id_mapping" ("UNIPROT_ACC","UNIPROT_ID","ENTREZ_GENE_ID") VALUES ('P01112','RASH_HUMAN',3265); -INSERT INTO "uniprot_id_mapping" ("UNIPROT_ACC","UNIPROT_ID","ENTREZ_GENE_ID") VALUES ('P01116','RASK_HUMAN',3845); -INSERT INTO "uniprot_id_mapping" ("UNIPROT_ACC","UNIPROT_ID","ENTREZ_GENE_ID") VALUES ('P01111','RASN_HUMAN',4893); - --- pfam_graphics -INSERT INTO "pfam_graphics" ("UNIPROT_ACC","JSON_DATA") VALUES ('P31749','[{\"length\":\"480\",\"regions\":[{\"modelStart\":\"1\",\"modelEnd\":\"102\",\"colour\":\"#2dcf00\",\"endStyle\":\"jagged\",\"end\":108,\"display\":true,\"startStyle\":\"curved\",\"aliEnd\":\"106\",\"modelLength\":\"104\",\"text\":\"PH\",\"href\":\"/family/PF00169\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"7.7e-10\",\"description\":\"PH domain\",\"end\":\"108\",\"accession\":\"PF00169\",\"database\":\"pfam\",\"aliEnd\":\"106\",\"identifier\":\"PH\",\"type\":\"Domain\",\"aliStart\":\"6\",\"start\":\"6\"},\"aliStart\":\"6\",\"start\":6},{\"modelStart\":\"2\",\"modelEnd\":\"260\",\"colour\":\"#ff5353\",\"endStyle\":\"curved\",\"end\":\"408\",\"display\":true,\"startStyle\":\"jagged\",\"aliEnd\":\"408\",\"modelLength\":\"260\",\"text\":\"Pkinase\",\"href\":\"/family/PF00069\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"1.2e-71\",\"description\":\"Protein kinase domain\",\"end\":\"408\",\"accession\":\"PF00069\",\"database\":\"pfam\",\"aliEnd\":\"408\",\"identifier\":\"Pkinase\",\"type\":\"Domain\",\"aliStart\":\"151\",\"start\":\"150\"},\"aliStart\":\"151\",\"start\":\"150\"},{\"modelStart\":\"1\",\"modelEnd\":\"45\",\"colour\":\"#5b5bff\",\"endStyle\":\"straight\",\"end\":\"477\",\"display\":true,\"startStyle\":\"straight\",\"aliEnd\":\"475\",\"modelLength\":\"48\",\"text\":\"Pkinase_C\",\"href\":\"/family/PF00433\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"0.00051\",\"description\":\"Protein kinase C terminal domain\",\"end\":\"477\",\"accession\":\"PF00433\",\"database\":\"pfam\",\"aliEnd\":\"475\",\"identifier\":\"Pkinase_C\",\"type\":\"Family\",\"aliStart\":\"428\",\"start\":\"428\"},\"aliStart\":\"428\",\"start\":\"428\"}],\"markups\":[{\"lineColour\":\"#ff0000\",\"colour\":\"#aaaaaa\",\"end\":77,\"display\":true,\"v_align\":\"top\",\"metadata\":{\"database\":\"UniProt\",\"type\":\"disulphide\",\"start\":\"60\",\"end\":\"77\"},\"type\":\"disulphide\",\"start\":60},{\"lineColour\":\"#ff0000\",\"colour\":\"#aaaaaa\",\"end\":\"310\",\"display\":true,\"v_align\":\"top\",\"metadata\":{\"database\":\"UniProt\",\"type\":\"disulphide\",\"start\":\"296\",\"end\":\"310\"},\"type\":\"disulphide\",\"start\":\"296\"}],\"metadata\":{\"database\":\"uniprot\",\"identifier\":\"AKT1_HUMAN\",\"description\":\"RAC-alpha serine/threonine-protein kinase EC=2.7.11.1\",\"organism\":\"Homo sapiens (Human)\",\"accession\":\"P31749\",\"taxid\":\"9606\"},\"motifs\":[{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"39\",\"end\":\"43\"},\"start\":39,\"end\":43,\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"47\",\"end\":\"50\"},\"start\":47,\"end\":50,\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"59\",\"end\":\"61\"},\"start\":59,\"end\":61,\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"101\",\"end\":\"106\"},\"start\":101,\"end\":106,\"display\":false},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"114\",\"end\":\"138\"},\"start\":114,\"end\":\"138\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"390\",\"end\":\"391\"},\"start\":\"390\",\"end\":\"391\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"393\",\"end\":\"396\"},\"start\":\"393\",\"end\":\"396\",\"display\":false},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"424\",\"end\":\"425\"},\"start\":\"424\",\"end\":\"425\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"448\",\"end\":\"464\"},\"start\":\"448\",\"end\":\"464\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"471\",\"end\":\"474\"},\"start\":\"471\",\"end\":\"474\",\"display\":false}]}]'); -INSERT INTO "pfam_graphics" ("UNIPROT_ACC","JSON_DATA") VALUES ('P31751','[{\"length\":\"481\",\"regions\":[{\"modelStart\":\"1\",\"modelEnd\":\"102\",\"colour\":\"#2dcf00\",\"endStyle\":\"jagged\",\"end\":108,\"display\":true,\"startStyle\":\"curved\",\"aliEnd\":\"106\",\"modelLength\":\"104\",\"text\":\"PH\",\"href\":\"/family/PF00169\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"1.5e-10\",\"description\":\"PH domain\",\"end\":\"108\",\"accession\":\"PF00169\",\"database\":\"pfam\",\"aliEnd\":\"106\",\"identifier\":\"PH\",\"type\":\"Domain\",\"aliStart\":\"6\",\"start\":\"6\"},\"aliStart\":\"6\",\"start\":6},{\"modelStart\":\"3\",\"modelEnd\":\"260\",\"colour\":\"#ff5353\",\"endStyle\":\"curved\",\"end\":\"409\",\"display\":true,\"startStyle\":\"jagged\",\"aliEnd\":\"409\",\"modelLength\":\"260\",\"text\":\"Pkinase\",\"href\":\"/family/PF00069\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"1.1e-71\",\"description\":\"Protein kinase domain\",\"end\":\"409\",\"accession\":\"PF00069\",\"database\":\"pfam\",\"aliEnd\":\"409\",\"identifier\":\"Pkinase\",\"type\":\"Domain\",\"aliStart\":\"154\",\"start\":\"152\"},\"aliStart\":\"154\",\"start\":\"152\"},{\"modelStart\":\"1\",\"modelEnd\":\"45\",\"colour\":\"#5b5bff\",\"endStyle\":\"straight\",\"end\":\"478\",\"display\":true,\"startStyle\":\"straight\",\"aliEnd\":\"476\",\"modelLength\":\"48\",\"text\":\"Pkinase_C\",\"href\":\"/family/PF00433\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"0.0013\",\"description\":\"Protein kinase C terminal domain\",\"end\":\"478\",\"accession\":\"PF00433\",\"database\":\"pfam\",\"aliEnd\":\"476\",\"identifier\":\"Pkinase_C\",\"type\":\"Family\",\"aliStart\":\"429\",\"start\":\"429\"},\"aliStart\":\"429\",\"start\":\"429\"}],\"markups\":[{\"lineColour\":\"#ff0000\",\"colour\":\"#aaaaaa\",\"end\":77,\"display\":true,\"v_align\":\"top\",\"metadata\":{\"database\":\"UniProt\",\"type\":\"disulphide\",\"start\":\"60\",\"end\":\"77\"},\"type\":\"disulphide\",\"start\":60},{\"lineColour\":\"#ff0000\",\"colour\":\"#aaaaaa\",\"end\":\"311\",\"display\":true,\"v_align\":\"top\",\"metadata\":{\"database\":\"UniProt\",\"type\":\"disulphide\",\"start\":\"297\",\"end\":\"311\"},\"type\":\"disulphide\",\"start\":\"297\"}],\"metadata\":{\"database\":\"uniprot\",\"identifier\":\"AKT2_HUMAN\",\"description\":\"RAC-beta serine/threonine-protein kinase EC=2.7.11.1\",\"organism\":\"Homo sapiens (Human)\",\"accession\":\"P31751\",\"taxid\":\"9606\"},\"motifs\":[{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"39\",\"end\":\"43\"},\"start\":39,\"end\":43,\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"47\",\"end\":\"50\"},\"start\":47,\"end\":50,\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"60\",\"end\":\"61\"},\"start\":60,\"end\":61,\"display\":false},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"116\",\"end\":\"129\"},\"start\":116,\"end\":\"129\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"133\",\"end\":\"137\"},\"start\":\"133\",\"end\":\"137\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"139\",\"end\":\"140\"},\"start\":\"139\",\"end\":\"140\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"394\",\"end\":\"397\"},\"start\":\"394\",\"end\":\"397\",\"display\":false}]}]'); -INSERT INTO "pfam_graphics" ("UNIPROT_ACC","JSON_DATA") VALUES ('P10398','[{\"length\":\"606\",\"regions\":[{\"modelStart\":\"2\",\"modelEnd\":\"71\",\"colour\":\"#2dcf00\",\"endStyle\":\"curved\",\"end\":91,\"display\":true,\"startStyle\":\"jagged\",\"aliEnd\":\"91\",\"modelLength\":\"71\",\"text\":\"RBD\",\"href\":\"/family/PF02196\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"3.2e-25\",\"description\":\"Raf-like Ras-binding domain\",\"end\":\"91\",\"accession\":\"PF02196\",\"database\":\"pfam\",\"aliEnd\":\"91\",\"identifier\":\"RBD\",\"type\":\"Domain\",\"aliStart\":\"20\",\"start\":\"19\"},\"aliStart\":\"20\",\"start\":19},{\"modelStart\":\"1\",\"modelEnd\":\"51\",\"colour\":\"#ff5353\",\"endStyle\":\"straight\",\"end\":\"147\",\"display\":true,\"startStyle\":\"straight\",\"aliEnd\":\"145\",\"modelLength\":\"53\",\"text\":\"C1_1\",\"href\":\"/family/PF00130\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"8.6e-07\",\"description\":\"Phorbol esters/diacylglycerol binding domain (C1 domain)\",\"end\":\"147\",\"accession\":\"PF00130\",\"database\":\"pfam\",\"aliEnd\":\"145\",\"identifier\":\"C1_1\",\"type\":\"Domain\",\"aliStart\":\"99\",\"start\":\"99\"},\"aliStart\":\"99\",\"start\":99},{\"modelStart\":\"2\",\"modelEnd\":\"257\",\"colour\":\"#5b5bff\",\"endStyle\":\"jagged\",\"end\":\"567\",\"display\":true,\"startStyle\":\"jagged\",\"aliEnd\":\"565\",\"modelLength\":\"259\",\"text\":\"Pkinase_Tyr\",\"href\":\"/family/PF07714\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"1.2e-57\",\"description\":\"Protein tyrosine kinase\",\"end\":\"567\",\"accession\":\"PF07714\",\"database\":\"pfam\",\"aliEnd\":\"565\",\"identifier\":\"Pkinase_Tyr\",\"type\":\"Domain\",\"aliStart\":\"311\",\"start\":\"310\"},\"aliStart\":\"311\",\"start\":\"310\"}],\"markups\":[],\"metadata\":{\"database\":\"uniprot\",\"identifier\":\"ARAF_HUMAN\",\"description\":\"Serine/threonine-protein kinase A-Raf EC=2.7.11.1\",\"organism\":\"Homo sapiens (Human)\",\"accession\":\"P10398\",\"taxid\":\"9606\"},\"motifs\":[{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1\",\"end\":\"13\"},\"start\":1,\"end\":13,\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"156\",\"end\":\"290\"},\"start\":\"156\",\"end\":\"290\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"351\",\"end\":\"352\"},\"start\":\"351\",\"end\":\"352\",\"display\":false},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"581\",\"end\":\"582\"},\"start\":\"581\",\"end\":\"582\",\"display\":true}]}]'); -INSERT INTO "pfam_graphics" ("UNIPROT_ACC","JSON_DATA") VALUES ('Q13315','[{\"length\":\"3056\",\"regions\":[{\"modelStart\":\"3\",\"modelEnd\":\"154\",\"colour\":\"#2dcf00\",\"endStyle\":\"jagged\",\"end\":\"166\",\"display\":true,\"startStyle\":\"jagged\",\"aliEnd\":\"165\",\"modelLength\":\"155\",\"text\":\"TAN\",\"href\":\"/family/PF11640\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"1.5e-32\",\"description\":\"Telomere-length maintenance and DNA damage repair\",\"end\":\"166\",\"accession\":\"PF11640\",\"database\":\"pfam\",\"aliEnd\":\"165\",\"identifier\":\"TAN\",\"type\":\"Domain\",\"aliStart\":\"7\",\"start\":\"5\"},\"aliStart\":\"7\",\"start\":5},{\"modelStart\":\"2\",\"modelEnd\":\"351\",\"colour\":\"#ff5353\",\"endStyle\":\"jagged\",\"end\":\"2489\",\"display\":true,\"startStyle\":\"jagged\",\"aliEnd\":\"2488\",\"modelLength\":\"352\",\"text\":\"FAT\",\"href\":\"/family/PF02259\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"2.2e-45\",\"description\":\"FAT domain\",\"end\":\"2489\",\"accession\":\"PF02259\",\"database\":\"pfam\",\"aliEnd\":\"2488\",\"identifier\":\"FAT\",\"type\":\"Family\",\"aliStart\":\"2097\",\"start\":\"2096\"},\"aliStart\":\"2097\",\"start\":\"2096\"},{\"modelStart\":\"4\",\"modelEnd\":\"234\",\"colour\":\"#5b5bff\",\"endStyle\":\"jagged\",\"end\":\"2962\",\"display\":true,\"startStyle\":\"jagged\",\"aliEnd\":\"2961\",\"modelLength\":\"235\",\"text\":\"PI3_PI4_kinase\",\"href\":\"/family/PF00454\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"8.6e-42\",\"description\":\"Phosphatidylinositol 3- and 4-kinase\",\"end\":\"2962\",\"accession\":\"PF00454\",\"database\":\"pfam\",\"aliEnd\":\"2961\",\"identifier\":\"PI3_PI4_kinase\",\"type\":\"Family\",\"aliStart\":\"2714\",\"start\":\"2711\"},\"aliStart\":\"2714\",\"start\":\"2711\"},{\"modelStart\":\"2\",\"modelEnd\":\"32\",\"colour\":\"#ebd61d\",\"endStyle\":\"straight\",\"end\":\"3056\",\"display\":true,\"startStyle\":\"straight\",\"aliEnd\":\"3055\",\"modelLength\":\"33\",\"text\":\"FATC\",\"href\":\"/family/PF02260\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"5.5e-08\",\"description\":\"FATC domain\",\"end\":\"3056\",\"accession\":\"PF02260\",\"database\":\"pfam\",\"aliEnd\":\"3055\",\"identifier\":\"FATC\",\"type\":\"Family\",\"aliStart\":\"3025\",\"start\":\"3024\"},\"aliStart\":\"3025\",\"start\":\"3024\"}],\"markups\":[],\"metadata\":{\"database\":\"uniprot\",\"identifier\":\"ATM_HUMAN\",\"description\":\"Serine-protein kinase ATM EC=2.7.11.1\",\"organism\":\"Homo sapiens (Human)\",\"accession\":\"Q13315\",\"taxid\":\"9606\"},\"motifs\":[{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"41\",\"end\":\"42\"},\"start\":41,\"end\":42,\"display\":false},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"837\",\"end\":\"846\"},\"start\":\"837\",\"end\":\"846\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"863\",\"end\":\"874\"},\"start\":\"863\",\"end\":\"874\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"876\",\"end\":\"878\"},\"start\":\"876\",\"end\":\"878\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1131\",\"end\":\"1132\"},\"start\":\"1131\",\"end\":\"1132\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1135\",\"end\":\"1136\"},\"start\":\"1135\",\"end\":\"1136\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1138\",\"end\":\"1139\"},\"start\":\"1138\",\"end\":\"1139\",\"display\":false},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1972\",\"end\":\"1977\"},\"start\":\"1972\",\"end\":\"1977\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1986\",\"end\":\"1989\"},\"start\":\"1986\",\"end\":\"1989\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2582\",\"end\":\"2595\"},\"start\":\"2582\",\"end\":\"2595\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2715\",\"end\":\"2716\"},\"start\":\"2715\",\"end\":\"2716\",\"display\":false},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2978\",\"end\":\"2986\"},\"start\":\"2978\",\"end\":\"2986\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"coiled_coil\",\"metadata\":{\"database\":\"ncoils\",\"type\":\"coiled_coil\",\"start\":\"1614\",\"end\":\"1634\"},\"start\":\"1614\",\"end\":\"1634\",\"display\":false},{\"colour\":\"#32cd32\",\"type\":\"coiled_coil\",\"metadata\":{\"database\":\"ncoils\",\"type\":\"coiled_coil\",\"start\":\"3003\",\"end\":\"3023\"},\"start\":\"3003\",\"end\":\"3023\",\"display\":true},{\"colour\":\"#86bcff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"2.2900\",\"type\":\"low_complexity\",\"start\":\"432\",\"end\":\"446\"},\"start\":\"432\",\"end\":\"446\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"2.1300\",\"type\":\"low_complexity\",\"start\":\"641\",\"end\":\"653\"},\"start\":\"641\",\"end\":\"653\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"2.2700\",\"type\":\"low_complexity\",\"start\":\"894\",\"end\":\"907\"},\"start\":\"894\",\"end\":\"907\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"2.4000\",\"type\":\"low_complexity\",\"start\":\"2443\",\"end\":\"2458\"},\"start\":\"2443\",\"end\":\"2458\",\"display\":false},{\"colour\":[\"#f0ff7f\",\"#7ff0ff\",\"#ff7ff0\"],\"href\":\"/pfamb/PB013450\",\"type\":\"pfamb\",\"metadata\":{\"database\":\"pfam\",\"identifier\":\"Pfam-B_13450\",\"type\":\"Pfam-B\",\"start\":\"602\",\"end\":\"830\",\"accession\":\"PB013450\"},\"start\":\"602\",\"end\":\"830\",\"display\":true},{\"colour\":[\"#7fff7f\",\"#7f7fff\",\"#ff7f7f\"],\"href\":\"/pfamb/PB017604\",\"type\":\"pfamb\",\"metadata\":{\"database\":\"pfam\",\"identifier\":\"Pfam-B_17604\",\"type\":\"Pfam-B\",\"start\":\"1819\",\"end\":\"1953\",\"accession\":\"PB017604\"},\"start\":\"1819\",\"end\":\"1953\",\"display\":true},{\"colour\":[\"#7ffff0\",\"#f07fff\",\"#fff07f\"],\"href\":\"/pfamb/PB016049\",\"type\":\"pfamb\",\"metadata\":{\"database\":\"pfam\",\"identifier\":\"Pfam-B_16049\",\"type\":\"Pfam-B\",\"start\":\"1715\",\"end\":\"1818\",\"accession\":\"PB016049\"},\"start\":\"1715\",\"end\":\"1818\",\"display\":true},{\"colour\":[\"#7f9dff\",\"#ff7f9d\",\"#9dff7f\"],\"href\":\"/pfamb/PB010220\",\"type\":\"pfamb\",\"metadata\":{\"database\":\"pfam\",\"identifier\":\"Pfam-B_10220\",\"type\":\"Pfam-B\",\"start\":\"1575\",\"end\":\"1713\",\"accession\":\"PB010220\"},\"start\":\"1575\",\"end\":\"1713\",\"display\":true},{\"colour\":[\"#d27fff\",\"#ffd27f\",\"#7fffd2\"],\"href\":\"/pfamb/PB003386\",\"type\":\"pfamb\",\"metadata\":{\"database\":\"pfam\",\"identifier\":\"Pfam-B_3386\",\"type\":\"Pfam-B\",\"start\":\"861\",\"end\":\"1458\",\"accession\":\"PB003386\"},\"start\":\"861\",\"end\":\"1458\",\"display\":true}]}]'); -INSERT INTO "pfam_graphics" ("UNIPROT_ACC","JSON_DATA") VALUES ('P38398','[{\"length\":\"1863\",\"regions\":[{\"modelStart\":\"1\",\"modelEnd\":\"41\",\"colour\":\"#2dcf00\",\"endStyle\":\"straight\",\"end\":64,\"display\":true,\"startStyle\":\"straight\",\"aliEnd\":\"64\",\"modelLength\":\"41\",\"text\":\"zf-C3HC4\",\"href\":\"/family/PF00097\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"6.6e-06\",\"description\":\"Zinc finger,C3HC4 type (RING finger)\",\"end\":\"64\",\"accession\":\"PF00097\",\"database\":\"pfam\",\"aliEnd\":\"64\",\"identifier\":\"zf-C3HC4\",\"type\":\"Domain\",\"aliStart\":\"24\",\"start\":\"24\"},\"aliStart\":\"24\",\"start\":24},{\"modelStart\":\"1\",\"modelEnd\":\"164\",\"colour\":\"#ff5353\",\"endStyle\":\"jagged\",\"end\":\"508\",\"display\":true,\"startStyle\":\"curved\",\"aliEnd\":\"507\",\"modelLength\":\"165\",\"text\":\"BRCT_assoc\",\"href\":\"/family/PF12820\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"6.4e-83\",\"description\":\"Serine-rich domain associated with BRCT\",\"end\":\"508\",\"accession\":\"PF12820\",\"database\":\"pfam\",\"aliEnd\":\"507\",\"identifier\":\"BRCT_assoc\",\"type\":\"Domain\",\"aliStart\":\"344\",\"start\":\"344\"},\"aliStart\":\"344\",\"start\":\"344\"},{\"modelStart\":\"1\",\"modelEnd\":\"354\",\"colour\":\"#5b5bff\",\"endStyle\":\"curved\",\"end\":\"978\",\"display\":true,\"startStyle\":\"curved\",\"aliEnd\":\"978\",\"modelLength\":\"354\",\"text\":\"EIN3\",\"href\":\"/family/PF04873\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"1.2e-89\",\"description\":\"Ethylene insensitive 3\",\"end\":\"978\",\"accession\":\"PF04873\",\"database\":\"pfam\",\"aliEnd\":\"978\",\"identifier\":\"EIN3\",\"type\":\"Family\",\"aliStart\":\"648\",\"start\":\"648\"},\"aliStart\":\"648\",\"start\":\"648\"},{\"modelStart\":\"24\",\"modelEnd\":\"78\",\"colour\":\"#ebd61d\",\"endStyle\":\"curved\",\"end\":\"1723\",\"display\":true,\"startStyle\":\"jagged\",\"aliEnd\":\"1723\",\"modelLength\":\"78\",\"text\":\"BRCT\",\"href\":\"/family/PF00533\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"0.00016\",\"description\":\"BRCA1 C Terminus (BRCT) domain\",\"end\":\"1723\",\"accession\":\"PF00533\",\"database\":\"pfam\",\"aliEnd\":\"1723\",\"identifier\":\"BRCT\",\"type\":\"Family\",\"aliStart\":\"1662\",\"start\":\"1648\"},\"aliStart\":\"1662\",\"start\":\"1648\"},{\"modelStart\":\"2\",\"modelEnd\":\"78\",\"colour\":\"#ebd61d\",\"endStyle\":\"curved\",\"end\":\"1842\",\"display\":true,\"startStyle\":\"jagged\",\"aliEnd\":\"1842\",\"modelLength\":\"78\",\"text\":\"BRCT\",\"href\":\"/family/PF00533\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"3.3e-05\",\"description\":\"BRCA1 C Terminus (BRCT) domain\",\"end\":\"1842\",\"accession\":\"PF00533\",\"database\":\"pfam\",\"aliEnd\":\"1842\",\"identifier\":\"BRCT\",\"type\":\"Family\",\"aliStart\":\"1757\",\"start\":\"1756\"},\"aliStart\":\"1757\",\"start\":\"1756\"}],\"markups\":[],\"metadata\":{\"database\":\"uniprot\",\"identifier\":\"BRCA1_HUMAN\",\"description\":\"Breast cancer type 1 susceptibility protein EC=6.3.2.-\",\"organism\":\"Homo sapiens (Human)\",\"accession\":\"P38398\",\"taxid\":\"9606\"},\"motifs\":[{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"135\",\"end\":\"153\"},\"start\":\"135\",\"end\":\"153\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"163\",\"end\":\"168\"},\"start\":\"163\",\"end\":\"168\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"176\",\"end\":\"184\"},\"start\":\"176\",\"end\":\"184\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"191\",\"end\":\"195\"},\"start\":\"191\",\"end\":\"195\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"202\",\"end\":\"204\"},\"start\":\"202\",\"end\":\"204\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"207\",\"end\":\"216\"},\"start\":\"207\",\"end\":\"216\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"218\",\"end\":\"221\"},\"start\":\"218\",\"end\":\"221\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"227\",\"end\":\"293\"},\"start\":\"227\",\"end\":\"293\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"301\",\"end\":\"346\"},\"start\":\"301\",\"end\":343,\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"353\",\"end\":\"367\"},\"start\":\"353\",\"end\":\"367\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"371\",\"end\":\"373\"},\"start\":\"371\",\"end\":\"373\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"390\",\"end\":\"410\"},\"start\":\"390\",\"end\":\"410\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"426\",\"end\":\"428\"},\"start\":\"426\",\"end\":\"428\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"443\",\"end\":\"444\"},\"start\":\"443\",\"end\":\"444\",\"display\":false},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"494\",\"end\":\"629\"},\"start\":545,\"end\":\"629\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"631\",\"end\":\"632\"},\"start\":\"631\",\"end\":\"632\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"636\",\"end\":\"643\"},\"start\":\"636\",\"end\":642,\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"647\",\"end\":\"706\"},\"start\":\"647\",\"end\":647,\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"708\",\"end\":\"709\"},\"start\":\"708\",\"end\":\"709\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"713\",\"end\":\"714\"},\"start\":\"713\",\"end\":\"714\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"718\",\"end\":\"776\"},\"start\":\"718\",\"end\":\"776\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"782\",\"end\":\"783\"},\"start\":\"782\",\"end\":\"783\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"786\",\"end\":\"789\"},\"start\":\"786\",\"end\":\"789\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"816\",\"end\":\"821\"},\"start\":\"816\",\"end\":\"821\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"825\",\"end\":\"851\"},\"start\":\"825\",\"end\":\"851\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"856\",\"end\":\"857\"},\"start\":\"856\",\"end\":\"857\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"868\",\"end\":\"870\"},\"start\":\"868\",\"end\":\"870\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"872\",\"end\":\"873\"},\"start\":\"872\",\"end\":\"873\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"880\",\"end\":\"881\"},\"start\":\"880\",\"end\":\"881\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"883\",\"end\":\"887\"},\"start\":\"883\",\"end\":\"887\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"896\",\"end\":\"920\"},\"start\":\"896\",\"end\":\"920\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"927\",\"end\":\"932\"},\"start\":\"927\",\"end\":\"932\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"964\",\"end\":\"972\"},\"start\":\"964\",\"end\":\"972\",\"display\":false},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1000\",\"end\":\"1027\"},\"start\":\"1000\",\"end\":\"1027\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1030\",\"end\":\"1032\"},\"start\":\"1030\",\"end\":\"1032\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1034\",\"end\":\"1035\"},\"start\":\"1034\",\"end\":\"1035\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1037\",\"end\":\"1076\"},\"start\":\"1037\",\"end\":\"1076\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1080\",\"end\":\"1081\"},\"start\":\"1080\",\"end\":\"1081\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1095\",\"end\":\"1116\"},\"start\":\"1095\",\"end\":\"1116\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1127\",\"end\":\"1165\"},\"start\":\"1127\",\"end\":\"1165\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1185\",\"end\":\"1218\"},\"start\":\"1185\",\"end\":1208,\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1242\",\"end\":\"1251\"},\"start\":\"1242\",\"end\":\"1251\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1277\",\"end\":\"1279\"},\"start\":\"1277\",\"end\":\"1279\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1281\",\"end\":\"1282\"},\"start\":\"1281\",\"end\":\"1282\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1308\",\"end\":\"1309\"},\"start\":\"1308\",\"end\":\"1309\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1311\",\"end\":\"1505\"},\"start\":1494,\"end\":\"1505\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1507\",\"end\":\"1508\"},\"start\":\"1507\",\"end\":\"1508\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1512\",\"end\":\"1517\"},\"start\":\"1512\",\"end\":\"1517\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1519\",\"end\":\"1559\"},\"start\":\"1519\",\"end\":\"1559\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1563\",\"end\":\"1596\"},\"start\":1588,\"end\":\"1596\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1601\",\"end\":\"1645\"},\"start\":\"1601\",\"end\":\"1645\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1647\",\"end\":\"1648\"},\"start\":\"1647\",\"end\":1647,\"display\":false},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1740\",\"end\":\"1741\"},\"start\":\"1740\",\"end\":\"1741\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1745\",\"end\":\"1749\"},\"start\":\"1745\",\"end\":\"1749\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1751\",\"end\":\"1752\"},\"start\":\"1751\",\"end\":\"1752\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"transmembrane\",\"metadata\":{\"database\":\"Phobius\",\"type\":\"transmembrane\",\"start\":\"1701\",\"end\":\"1719\"},\"start\":\"1701\",\"end\":\"1719\",\"display\":false},{\"colour\":\"#32cd32\",\"type\":\"coiled_coil\",\"metadata\":{\"database\":\"ncoils\",\"type\":\"coiled_coil\",\"start\":\"1253\",\"end\":\"1273\"},\"start\":\"1253\",\"end\":\"1273\",\"display\":true},{\"colour\":\"#32cd32\",\"type\":\"coiled_coil\",\"metadata\":{\"database\":\"ncoils\",\"type\":\"coiled_coil\",\"start\":\"1397\",\"end\":\"1424\"},\"start\":\"1397\",\"end\":1403,\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"2.1900\",\"type\":\"low_complexity\",\"start\":\"394\",\"end\":\"405\"},\"start\":\"394\",\"end\":\"405\",\"display\":false},{\"colour\":\"#86bcff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"2.1900\",\"type\":\"low_complexity\",\"start\":\"533\",\"end\":\"544\"},\"start\":\"533\",\"end\":\"544\",\"display\":true},{\"colour\":\"#86bcff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"2.0800\",\"type\":\"low_complexity\",\"start\":\"643\",\"end\":\"654\"},\"start\":\"643\",\"end\":647,\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"1.3000\",\"type\":\"low_complexity\",\"start\":\"729\",\"end\":\"736\"},\"start\":\"729\",\"end\":\"736\",\"display\":false},{\"colour\":\"#86bcff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"2.0200\",\"type\":\"low_complexity\",\"start\":\"1209\",\"end\":\"1223\"},\"start\":\"1209\",\"end\":\"1223\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"2.4400\",\"type\":\"low_complexity\",\"start\":\"1254\",\"end\":\"1268\"},\"start\":\"1254\",\"end\":\"1268\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"2.2000\",\"type\":\"low_complexity\",\"start\":\"1425\",\"end\":\"1437\"},\"start\":\"1425\",\"end\":\"1437\",\"display\":false},{\"colour\":\"#86bcff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"2.4100\",\"type\":\"low_complexity\",\"start\":\"1572\",\"end\":\"1587\"},\"start\":\"1572\",\"end\":\"1587\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"2.4100\",\"type\":\"low_complexity\",\"start\":\"1673\",\"end\":\"1686\"},\"start\":\"1673\",\"end\":\"1686\",\"display\":false},{\"colour\":[\"#86ff7f\",\"#7f88ff\",\"#ff7f87\"],\"href\":\"/pfamb/PB017893\",\"type\":\"pfamb\",\"metadata\":{\"database\":\"pfam\",\"identifier\":\"Pfam-B_17893\",\"type\":\"Pfam-B\",\"start\":\"1404\",\"end\":\"1493\",\"accession\":\"PB017893\"},\"start\":\"1404\",\"end\":\"1493\",\"display\":true},{\"colour\":\"#00ffff\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1311\",\"end\":\"1505\"},\"type\":\"disorder\",\"display\":false,\"end\":1403,\"start\":1404},{\"colour\":\"#cccccc\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1311\",\"end\":\"1505\"},\"type\":\"disorder\",\"display\":true,\"end\":1396,\"start\":\"1311\"},{\"colour\":\"#cccccc\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"494\",\"end\":\"629\"},\"type\":\"disorder\",\"display\":true,\"end\":532,\"start\":509},{\"colour\":\"#cccccc\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1563\",\"end\":\"1596\"},\"type\":\"disorder\",\"display\":true,\"end\":1571,\"start\":\"1563\"}]}]'); -INSERT INTO "pfam_graphics" ("UNIPROT_ACC","JSON_DATA") VALUES ('P15056','[{\"length\":\"766\",\"regions\":[{\"modelStart\":\"2\",\"modelEnd\":\"71\",\"colour\":\"#2dcf00\",\"endStyle\":\"curved\",\"end\":\"227\",\"display\":true,\"startStyle\":\"jagged\",\"aliEnd\":\"227\",\"modelLength\":\"71\",\"text\":\"RBD\",\"href\":\"/family/PF02196\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"5.8e-27\",\"description\":\"Raf-like Ras-binding domain\",\"end\":\"227\",\"accession\":\"PF02196\",\"database\":\"pfam\",\"aliEnd\":\"227\",\"identifier\":\"RBD\",\"type\":\"Domain\",\"aliStart\":\"156\",\"start\":\"155\"},\"aliStart\":\"156\",\"start\":\"155\"},{\"modelStart\":\"1\",\"modelEnd\":\"50\",\"colour\":\"#ff5353\",\"endStyle\":\"straight\",\"end\":\"282\",\"display\":true,\"startStyle\":\"straight\",\"aliEnd\":\"280\",\"modelLength\":\"53\",\"text\":\"C1_1\",\"href\":\"/family/PF00130\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"2.3e-08\",\"description\":\"Phorbol esters/diacylglycerol binding domain (C1 domain)\",\"end\":\"282\",\"accession\":\"PF00130\",\"database\":\"pfam\",\"aliEnd\":\"280\",\"identifier\":\"C1_1\",\"type\":\"Domain\",\"aliStart\":\"235\",\"start\":\"235\"},\"aliStart\":\"235\",\"start\":\"235\"},{\"modelStart\":\"2\",\"modelEnd\":\"257\",\"colour\":\"#5b5bff\",\"endStyle\":\"jagged\",\"end\":\"714\",\"display\":true,\"startStyle\":\"jagged\",\"aliEnd\":\"712\",\"modelLength\":\"259\",\"text\":\"Pkinase_Tyr\",\"href\":\"/family/PF07714\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"4.4e-61\",\"description\":\"Protein tyrosine kinase\",\"end\":\"714\",\"accession\":\"PF07714\",\"database\":\"pfam\",\"aliEnd\":\"712\",\"identifier\":\"Pkinase_Tyr\",\"type\":\"Domain\",\"aliStart\":\"458\",\"start\":\"457\"},\"aliStart\":\"458\",\"start\":\"457\"}],\"markups\":[],\"metadata\":{\"database\":\"uniprot\",\"identifier\":\"BRAF_HUMAN\",\"description\":\"Serine/threonine-protein kinase B-raf EC=2.7.11.1\",\"organism\":\"Homo sapiens (Human)\",\"accession\":\"P15056\",\"taxid\":\"0\"},\"motifs\":[{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2\",\"end\":\"7\"},\"start\":2,\"end\":5,\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"9\",\"end\":\"38\"},\"start\":12,\"end\":26,\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"64\",\"end\":\"67\"},\"start\":64,\"end\":67,\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"96\",\"end\":\"97\"},\"start\":96,\"end\":97,\"display\":false},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"103\",\"end\":\"105\"},\"start\":103,\"end\":105,\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"111\",\"end\":\"116\"},\"start\":111,\"end\":116,\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"122\",\"end\":\"123\"},\"start\":122,\"end\":123,\"display\":false},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"141\",\"end\":\"149\"},\"start\":\"141\",\"end\":\"149\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"305\",\"end\":\"377\"},\"start\":344,\"end\":\"377\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"380\",\"end\":\"456\"},\"start\":433,\"end\":\"456\",\"display\":true},{\"colour\":\"#32cd32\",\"type\":\"coiled_coil\",\"metadata\":{\"database\":\"ncoils\",\"type\":\"coiled_coil\",\"start\":\"82\",\"end\":\"102\"},\"start\":82,\"end\":102,\"display\":true},{\"colour\":\"#86bcff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"type\":\"low_complexity\",\"start\":\"6\",\"end\":\"11\"},\"start\":6,\"end\":11,\"display\":true},{\"colour\":\"#86bcff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"1.3300\",\"type\":\"low_complexity\",\"start\":\"27\",\"end\":\"39\"},\"start\":27,\"end\":39,\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"2.0800\",\"type\":\"low_complexity\",\"start\":\"92\",\"end\":\"103\"},\"start\":103,\"end\":103,\"display\":false},{\"colour\":\"#86bcff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"2.1900\",\"type\":\"low_complexity\",\"start\":\"110\",\"end\":\"137\"},\"start\":110,\"end\":\"137\",\"display\":true},{\"colour\":\"#86bcff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"2.2900\",\"type\":\"low_complexity\",\"start\":\"314\",\"end\":\"328\"},\"start\":\"314\",\"end\":\"328\",\"display\":true},{\"colour\":\"#86bcff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"1.8200\",\"type\":\"low_complexity\",\"start\":\"333\",\"end\":\"343\"},\"start\":\"333\",\"end\":\"343\",\"display\":true},{\"colour\":\"#86bcff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"type\":\"low_complexity\",\"start\":\"428\",\"end\":\"432\"},\"start\":\"428\",\"end\":\"432\",\"display\":true},{\"colour\":\"#cccccc\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"305\",\"end\":\"377\"},\"type\":\"disorder\",\"display\":true,\"end\":313,\"start\":\"305\"},{\"colour\":\"#cccccc\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"305\",\"end\":\"377\"},\"type\":\"disorder\",\"display\":true,\"end\":332,\"start\":329},{\"colour\":\"#cccccc\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"380\",\"end\":\"456\"},\"type\":\"disorder\",\"display\":true,\"end\":427,\"start\":\"380\"}]}]'); -INSERT INTO "pfam_graphics" ("UNIPROT_ACC","JSON_DATA") VALUES ('P51587','[{\"length\":\"3418\",\"regions\":[{\"modelStart\":\"1\",\"modelEnd\":\"35\",\"colour\":\"#2dcf00\",\"endStyle\":\"straight\",\"end\":\"1036\",\"display\":true,\"startStyle\":\"straight\",\"aliEnd\":\"1036\",\"modelLength\":\"35\",\"text\":\"BRCA2\",\"href\":\"/family/PF00634\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"8.9e-09\",\"description\":\"BRCA2 repeat\",\"end\":\"1036\",\"accession\":\"PF00634\",\"database\":\"pfam\",\"aliEnd\":\"1036\",\"identifier\":\"BRCA2\",\"type\":\"Family\",\"aliStart\":\"1002\",\"start\":\"1002\"},\"aliStart\":\"1002\",\"start\":\"1002\"},{\"modelStart\":\"1\",\"modelEnd\":\"35\",\"colour\":\"#2dcf00\",\"endStyle\":\"straight\",\"end\":\"1246\",\"display\":true,\"startStyle\":\"straight\",\"aliEnd\":\"1246\",\"modelLength\":\"35\",\"text\":\"BRCA2\",\"href\":\"/family/PF00634\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"1.9e-08\",\"description\":\"BRCA2 repeat\",\"end\":\"1246\",\"accession\":\"PF00634\",\"database\":\"pfam\",\"aliEnd\":\"1246\",\"identifier\":\"BRCA2\",\"type\":\"Family\",\"aliStart\":\"1212\",\"start\":\"1212\"},\"aliStart\":\"1212\",\"start\":\"1212\"},{\"modelStart\":\"1\",\"modelEnd\":\"34\",\"colour\":\"#2dcf00\",\"endStyle\":\"straight\",\"end\":\"1455\",\"display\":true,\"startStyle\":\"straight\",\"aliEnd\":\"1454\",\"modelLength\":\"35\",\"text\":\"BRCA2\",\"href\":\"/family/PF00634\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"6.7e-08\",\"description\":\"BRCA2 repeat\",\"end\":\"1455\",\"accession\":\"PF00634\",\"database\":\"pfam\",\"aliEnd\":\"1454\",\"identifier\":\"BRCA2\",\"type\":\"Family\",\"aliStart\":\"1421\",\"start\":\"1421\"},\"aliStart\":\"1421\",\"start\":\"1421\"},{\"modelStart\":\"1\",\"modelEnd\":\"34\",\"colour\":\"#2dcf00\",\"endStyle\":\"straight\",\"end\":\"1551\",\"display\":true,\"startStyle\":\"straight\",\"aliEnd\":\"1550\",\"modelLength\":\"35\",\"text\":\"BRCA2\",\"href\":\"/family/PF00634\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"2.6e-10\",\"description\":\"BRCA2 repeat\",\"end\":\"1551\",\"accession\":\"PF00634\",\"database\":\"pfam\",\"aliEnd\":\"1550\",\"identifier\":\"BRCA2\",\"type\":\"Family\",\"aliStart\":\"1517\",\"start\":\"1517\"},\"aliStart\":\"1517\",\"start\":\"1517\"},{\"modelStart\":\"1\",\"modelEnd\":\"33\",\"colour\":\"#2dcf00\",\"endStyle\":\"straight\",\"end\":\"1698\",\"display\":true,\"startStyle\":\"straight\",\"aliEnd\":\"1696\",\"modelLength\":\"35\",\"text\":\"BRCA2\",\"href\":\"/family/PF00634\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"3.9e-08\",\"description\":\"BRCA2 repeat\",\"end\":\"1698\",\"accession\":\"PF00634\",\"database\":\"pfam\",\"aliEnd\":\"1696\",\"identifier\":\"BRCA2\",\"type\":\"Family\",\"aliStart\":\"1664\",\"start\":\"1664\"},\"aliStart\":\"1664\",\"start\":\"1664\"},{\"modelStart\":\"1\",\"modelEnd\":\"33\",\"colour\":\"#2dcf00\",\"endStyle\":\"straight\",\"end\":\"1871\",\"display\":true,\"startStyle\":\"straight\",\"aliEnd\":\"1869\",\"modelLength\":\"35\",\"text\":\"BRCA2\",\"href\":\"/family/PF00634\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"6.3e-08\",\"description\":\"BRCA2 repeat\",\"end\":\"1871\",\"accession\":\"PF00634\",\"database\":\"pfam\",\"aliEnd\":\"1869\",\"identifier\":\"BRCA2\",\"type\":\"Family\",\"aliStart\":\"1837\",\"start\":\"1837\"},\"aliStart\":\"1837\",\"start\":\"1837\"},{\"modelStart\":\"2\",\"modelEnd\":\"35\",\"colour\":\"#2dcf00\",\"endStyle\":\"straight\",\"end\":\"2005\",\"display\":true,\"startStyle\":\"straight\",\"aliEnd\":\"2005\",\"modelLength\":\"35\",\"text\":\"BRCA2\",\"href\":\"/family/PF00634\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"2e-10\",\"description\":\"BRCA2 repeat\",\"end\":\"2005\",\"accession\":\"PF00634\",\"database\":\"pfam\",\"aliEnd\":\"2005\",\"identifier\":\"BRCA2\",\"type\":\"Family\",\"aliStart\":\"1972\",\"start\":\"1971\"},\"aliStart\":\"1972\",\"start\":\"1971\"},{\"modelStart\":\"1\",\"modelEnd\":\"34\",\"colour\":\"#2dcf00\",\"endStyle\":\"straight\",\"end\":\"2085\",\"display\":true,\"startStyle\":\"straight\",\"aliEnd\":\"2084\",\"modelLength\":\"35\",\"text\":\"BRCA2\",\"href\":\"/family/PF00634\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"3.3e-08\",\"description\":\"BRCA2 repeat\",\"end\":\"2085\",\"accession\":\"PF00634\",\"database\":\"pfam\",\"aliEnd\":\"2084\",\"identifier\":\"BRCA2\",\"type\":\"Family\",\"aliStart\":\"2051\",\"start\":\"2051\"},\"aliStart\":\"2051\",\"start\":\"2051\"},{\"modelStart\":\"1\",\"modelEnd\":\"195\",\"colour\":\"#ff5353\",\"endStyle\":\"curved\",\"end\":\"2667\",\"display\":true,\"startStyle\":\"curved\",\"aliEnd\":\"2667\",\"modelLength\":\"195\",\"text\":\"BRCA-2_helical\",\"href\":\"/family/PF09169\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"1.5e-98\",\"description\":\"BRCA2,helical\",\"end\":\"2667\",\"accession\":\"PF09169\",\"database\":\"pfam\",\"aliEnd\":\"2667\",\"identifier\":\"BRCA-2_helical\",\"type\":\"Domain\",\"aliStart\":\"2479\",\"start\":\"2479\"},\"aliStart\":\"2479\",\"start\":\"2479\"},{\"modelStart\":\"1\",\"modelEnd\":\"117\",\"colour\":\"#5b5bff\",\"endStyle\":\"jagged\",\"end\":\"2800\",\"display\":true,\"startStyle\":\"curved\",\"aliEnd\":\"2799\",\"modelLength\":\"118\",\"text\":\"BRCA-2_OB1\",\"href\":\"/family/PF09103\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"1.3e-39\",\"description\":\"BRCA2,oligonucleotide/oligosaccharide-binding,domain 1\",\"end\":\"2800\",\"accession\":\"PF09103\",\"database\":\"pfam\",\"aliEnd\":\"2799\",\"identifier\":\"BRCA-2_OB1\",\"type\":\"Domain\",\"aliStart\":\"2670\",\"start\":\"2670\"},\"aliStart\":\"2670\",\"start\":\"2670\"},{\"modelStart\":\"1\",\"modelEnd\":\"42\",\"colour\":\"#ebd61d\",\"endStyle\":\"straight\",\"end\":\"2872\",\"display\":true,\"startStyle\":\"straight\",\"aliEnd\":\"2872\",\"modelLength\":\"42\",\"text\":\"Tower\",\"href\":\"/family/PF09121\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"4.9e-19\",\"description\":\"Tower\",\"end\":\"2872\",\"accession\":\"PF09121\",\"database\":\"pfam\",\"aliEnd\":\"2872\",\"identifier\":\"Tower\",\"type\":\"Domain\",\"aliStart\":\"2831\",\"start\":\"2831\"},\"aliStart\":\"2831\",\"start\":\"2831\"},{\"modelStart\":\"1\",\"modelEnd\":\"143\",\"colour\":\"#ba21e0\",\"endStyle\":\"curved\",\"end\":\"3190\",\"display\":true,\"startStyle\":\"curved\",\"aliEnd\":\"3190\",\"modelLength\":\"143\",\"text\":\"BRCA-2_OB3\",\"href\":\"/family/PF09104\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"2.7e-60\",\"description\":\"BRCA2,oligonucleotide/oligosaccharide-binding,domain 3\",\"end\":\"3190\",\"accession\":\"PF09104\",\"database\":\"pfam\",\"aliEnd\":\"3190\",\"identifier\":\"BRCA-2_OB3\",\"type\":\"Domain\",\"aliStart\":\"3052\",\"start\":\"3052\"},\"aliStart\":\"3052\",\"start\":\"3052\"}],\"markups\":[],\"metadata\":{\"database\":\"uniprot\",\"identifier\":\"BRCA2_HUMAN\",\"description\":\"Breast cancer type 2 susceptibility protein\",\"organism\":\"Homo sapiens (Human)\",\"accession\":\"P51587\",\"taxid\":\"9606\"},\"motifs\":[{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"38\",\"end\":\"68\"},\"start\":38,\"end\":68,\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"73\",\"end\":\"74\"},\"start\":73,\"end\":74,\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"102\",\"end\":\"104\"},\"start\":102,\"end\":104,\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"112\",\"end\":\"123\"},\"start\":112,\"end\":123,\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"176\",\"end\":\"187\"},\"start\":\"176\",\"end\":\"187\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"191\",\"end\":\"197\"},\"start\":\"191\",\"end\":192,\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"205\",\"end\":\"209\"},\"start\":208,\"end\":\"209\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"220\",\"end\":\"221\"},\"start\":\"220\",\"end\":\"221\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"232\",\"end\":\"234\"},\"start\":\"232\",\"end\":\"234\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"244\",\"end\":\"267\"},\"start\":\"244\",\"end\":\"267\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"277\",\"end\":\"279\"},\"start\":\"277\",\"end\":\"279\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"290\",\"end\":\"291\"},\"start\":\"290\",\"end\":\"291\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"293\",\"end\":\"296\"},\"start\":\"293\",\"end\":\"296\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"326\",\"end\":\"329\"},\"start\":\"326\",\"end\":\"329\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"334\",\"end\":\"336\"},\"start\":\"334\",\"end\":\"336\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"352\",\"end\":\"379\"},\"start\":\"352\",\"end\":\"379\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"425\",\"end\":\"427\"},\"start\":\"425\",\"end\":\"427\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"430\",\"end\":\"437\"},\"start\":\"430\",\"end\":\"437\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"439\",\"end\":\"471\"},\"start\":\"439\",\"end\":\"471\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"516\",\"end\":\"534\"},\"start\":\"516\",\"end\":\"534\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"540\",\"end\":\"541\"},\"start\":\"540\",\"end\":\"541\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"558\",\"end\":\"560\"},\"start\":\"558\",\"end\":\"560\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"644\",\"end\":\"645\"},\"start\":\"644\",\"end\":\"645\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"713\",\"end\":\"714\"},\"start\":\"713\",\"end\":\"714\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"722\",\"end\":\"724\"},\"start\":\"722\",\"end\":\"724\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"794\",\"end\":\"801\"},\"start\":\"794\",\"end\":\"801\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"803\",\"end\":\"811\"},\"start\":\"803\",\"end\":\"811\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"835\",\"end\":\"837\"},\"start\":\"835\",\"end\":\"837\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"844\",\"end\":\"847\"},\"start\":\"844\",\"end\":\"847\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"853\",\"end\":\"858\"},\"start\":\"853\",\"end\":\"858\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"860\",\"end\":\"863\"},\"start\":\"860\",\"end\":\"863\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"868\",\"end\":\"878\"},\"start\":\"868\",\"end\":\"878\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"902\",\"end\":\"905\"},\"start\":\"902\",\"end\":\"905\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"962\",\"end\":\"963\"},\"start\":\"962\",\"end\":\"963\",\"display\":false},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1097\",\"end\":\"1098\"},\"start\":\"1097\",\"end\":\"1098\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1102\",\"end\":\"1105\"},\"start\":\"1102\",\"end\":\"1105\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1108\",\"end\":\"1110\"},\"start\":\"1108\",\"end\":\"1110\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1153\",\"end\":\"1155\"},\"start\":\"1153\",\"end\":\"1155\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1252\",\"end\":\"1253\"},\"start\":\"1252\",\"end\":\"1253\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1255\",\"end\":\"1256\"},\"start\":\"1255\",\"end\":\"1256\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1305\",\"end\":\"1337\"},\"start\":\"1305\",\"end\":\"1337\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1400\",\"end\":\"1416\"},\"start\":\"1400\",\"end\":\"1416\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1461\",\"end\":\"1464\"},\"start\":\"1461\",\"end\":\"1464\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1501\",\"end\":\"1510\"},\"start\":\"1501\",\"end\":\"1510\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1517\",\"end\":\"1520\"},\"start\":\"1517\",\"end\":\"1520\",\"display\":false},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1602\",\"end\":\"1603\"},\"start\":\"1602\",\"end\":\"1603\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1648\",\"end\":\"1651\"},\"start\":\"1648\",\"end\":\"1651\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1709\",\"end\":\"1711\"},\"start\":\"1709\",\"end\":\"1711\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1722\",\"end\":\"1739\"},\"start\":\"1722\",\"end\":\"1739\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1743\",\"end\":\"1744\"},\"start\":\"1743\",\"end\":\"1744\",\"display\":false},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"1774\",\"end\":\"1775\"},\"start\":\"1774\",\"end\":\"1775\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2025\",\"end\":\"2033\"},\"start\":\"2025\",\"end\":\"2033\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2097\",\"end\":\"2100\"},\"start\":\"2097\",\"end\":\"2100\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2102\",\"end\":\"2114\"},\"start\":\"2102\",\"end\":\"2114\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2116\",\"end\":\"2120\"},\"start\":\"2116\",\"end\":\"2120\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2137\",\"end\":\"2139\"},\"start\":\"2137\",\"end\":\"2139\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2141\",\"end\":\"2144\"},\"start\":\"2141\",\"end\":\"2144\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2149\",\"end\":\"2153\"},\"start\":\"2149\",\"end\":\"2153\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2185\",\"end\":\"2188\"},\"start\":\"2185\",\"end\":\"2188\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2190\",\"end\":\"2197\"},\"start\":\"2190\",\"end\":\"2197\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2241\",\"end\":\"2242\"},\"start\":\"2241\",\"end\":\"2242\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2246\",\"end\":\"2252\"},\"start\":\"2246\",\"end\":\"2252\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2256\",\"end\":\"2257\"},\"start\":\"2256\",\"end\":\"2257\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2264\",\"end\":\"2267\"},\"start\":\"2264\",\"end\":\"2267\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2300\",\"end\":\"2311\"},\"start\":\"2300\",\"end\":\"2311\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2336\",\"end\":\"2339\"},\"start\":\"2336\",\"end\":\"2339\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2341\",\"end\":\"2351\"},\"start\":\"2341\",\"end\":\"2351\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2379\",\"end\":\"2384\"},\"start\":\"2379\",\"end\":\"2384\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2388\",\"end\":\"2404\"},\"start\":\"2388\",\"end\":\"2404\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2407\",\"end\":\"2410\"},\"start\":\"2407\",\"end\":\"2410\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2421\",\"end\":\"2425\"},\"start\":\"2421\",\"end\":\"2425\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2427\",\"end\":\"2458\"},\"start\":2449,\"end\":\"2458\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2460\",\"end\":\"2461\"},\"start\":\"2460\",\"end\":\"2461\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2465\",\"end\":\"2466\"},\"start\":\"2465\",\"end\":\"2466\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2491\",\"end\":\"2492\"},\"start\":\"2491\",\"end\":\"2492\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2494\",\"end\":\"2499\"},\"start\":\"2494\",\"end\":\"2499\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2852\",\"end\":\"2854\"},\"start\":\"2852\",\"end\":\"2854\",\"display\":false},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2876\",\"end\":\"2886\"},\"start\":2880,\"end\":\"2886\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2932\",\"end\":\"2934\"},\"start\":\"2932\",\"end\":\"2934\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"2947\",\"end\":\"2950\"},\"start\":\"2947\",\"end\":\"2950\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"3202\",\"end\":\"3203\"},\"start\":\"3202\",\"end\":\"3203\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"3245\",\"end\":\"3247\"},\"start\":\"3245\",\"end\":\"3247\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"3250\",\"end\":\"3253\"},\"start\":\"3250\",\"end\":\"3253\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"3257\",\"end\":\"3259\"},\"start\":\"3257\",\"end\":\"3259\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"3300\",\"end\":\"3301\"},\"start\":\"3300\",\"end\":\"3301\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"3309\",\"end\":\"3313\"},\"start\":\"3309\",\"end\":\"3313\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"3315\",\"end\":\"3316\"},\"start\":\"3315\",\"end\":\"3316\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"3319\",\"end\":\"3321\"},\"start\":\"3319\",\"end\":\"3321\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"3363\",\"end\":\"3368\"},\"start\":\"3363\",\"end\":\"3368\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"3373\",\"end\":\"3374\"},\"start\":\"3373\",\"end\":\"3374\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"3376\",\"end\":\"3378\"},\"start\":\"3376\",\"end\":\"3378\",\"display\":true},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"3391\",\"end\":\"3408\"},\"start\":\"3391\",\"end\":\"3408\",\"display\":true},{\"colour\":\"#32cd32\",\"type\":\"coiled_coil\",\"metadata\":{\"database\":\"ncoils\",\"type\":\"coiled_coil\",\"start\":\"2855\",\"end\":\"2879\"},\"start\":2873,\"end\":\"2879\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"coiled_coil\",\"metadata\":{\"database\":\"ncoils\",\"type\":\"coiled_coil\",\"start\":\"3159\",\"end\":\"3179\"},\"start\":\"3159\",\"end\":\"3179\",\"display\":false},{\"colour\":\"#86bcff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"2.2900\",\"type\":\"low_complexity\",\"start\":\"193\",\"end\":\"207\"},\"start\":\"193\",\"end\":\"207\",\"display\":true},{\"colour\":\"#86bcff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"1.8800\",\"type\":\"low_complexity\",\"start\":\"1741\",\"end\":\"1753\"},\"start\":\"1741\",\"end\":\"1753\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"2.1200\",\"type\":\"low_complexity\",\"start\":\"2052\",\"end\":\"2063\"},\"start\":\"2052\",\"end\":\"2063\",\"display\":false},{\"colour\":\"#86bcff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"2.6800\",\"type\":\"low_complexity\",\"start\":\"2792\",\"end\":\"2813\"},\"start\":2801,\"end\":\"2813\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"2.5000\",\"type\":\"low_complexity\",\"start\":\"2844\",\"end\":\"2860\"},\"start\":\"2844\",\"end\":\"2860\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"1.0600\",\"type\":\"low_complexity\",\"start\":\"2871\",\"end\":\"2878\"},\"start\":2873,\"end\":\"2878\",\"display\":false},{\"colour\":\"#86bcff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"2.0500\",\"type\":\"low_complexity\",\"start\":\"3274\",\"end\":\"3285\"},\"start\":\"3274\",\"end\":\"3285\",\"display\":true},{\"colour\":[\"#7fb1ff\",\"#ff7fb2\",\"#b2ff7f\"],\"href\":\"/pfamb/PB008258\",\"type\":\"pfamb\",\"metadata\":{\"database\":\"pfam\",\"identifier\":\"Pfam-B_8258\",\"type\":\"Pfam-B\",\"start\":\"651\",\"end\":\"989\",\"accession\":\"PB008258\"},\"start\":\"651\",\"end\":\"989\",\"display\":true},{\"colour\":[\"#bd7fff\",\"#ffbd7f\",\"#7fffbd\"],\"href\":\"/pfamb/PB047717\",\"type\":\"pfamb\",\"metadata\":{\"database\":\"pfam\",\"identifier\":\"Pfam-B_47717\",\"type\":\"Pfam-B\",\"start\":\"2449\",\"end\":\"2478\",\"accession\":\"PB047717\"},\"start\":\"2449\",\"end\":\"2478\",\"display\":true},{\"colour\":[\"#ff7fcf\",\"#d0ff7f\",\"#7fd0ff\"],\"href\":\"/pfamb/PB013057\",\"type\":\"pfamb\",\"metadata\":{\"database\":\"pfam\",\"identifier\":\"Pfam-B_13057\",\"type\":\"Pfam-B\",\"start\":\"2141\",\"end\":\"2448\",\"accession\":\"PB013057\"},\"start\":\"2141\",\"end\":\"2448\",\"display\":true}]}]'); -INSERT INTO "pfam_graphics" ("UNIPROT_ACC","JSON_DATA") VALUES ('P01112','[{\"length\":\"189\",\"regions\":[{\"modelStart\":\"1\",\"modelEnd\":\"161\",\"colour\":\"#2dcf00\",\"endStyle\":\"jagged\",\"end\":\"165\",\"display\":true,\"startStyle\":\"curved\",\"aliEnd\":\"164\",\"modelLength\":\"162\",\"text\":\"Ras\",\"href\":\"/family/PF00071\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"3.2e-55\",\"description\":\"Ras family\",\"end\":\"165\",\"accession\":\"PF00071\",\"database\":\"pfam\",\"aliEnd\":\"164\",\"identifier\":\"Ras\",\"type\":\"Domain\",\"aliStart\":\"5\",\"start\":\"5\"},\"aliStart\":\"5\",\"start\":5}],\"markups\":[],\"metadata\":{\"database\":\"uniprot\",\"identifier\":\"RASH_HUMAN\",\"description\":\"GTPase HRas\",\"organism\":\"Homo sapiens (Human)\",\"accession\":\"P01112\",\"taxid\":\"9606\"},\"motifs\":[{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"168\",\"end\":\"172\"},\"start\":\"168\",\"end\":\"172\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"1.3900\",\"type\":\"low_complexity\",\"start\":\"7\",\"end\":\"15\"},\"start\":7,\"end\":15,\"display\":false}]}]'); -INSERT INTO "pfam_graphics" ("UNIPROT_ACC","JSON_DATA") VALUES ('P01116','[{\"length\":\"189\",\"regions\":[{\"modelStart\":\"1\",\"modelEnd\":\"161\",\"colour\":\"#2dcf00\",\"endStyle\":\"jagged\",\"end\":\"165\",\"display\":true,\"startStyle\":\"curved\",\"aliEnd\":\"164\",\"modelLength\":\"162\",\"text\":\"Ras\",\"href\":\"/family/PF00071\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"4.2e-55\",\"description\":\"Ras family\",\"end\":\"165\",\"accession\":\"PF00071\",\"database\":\"pfam\",\"aliEnd\":\"164\",\"identifier\":\"Ras\",\"type\":\"Domain\",\"aliStart\":\"5\",\"start\":\"5\"},\"aliStart\":\"5\",\"start\":5}],\"markups\":[],\"metadata\":{\"database\":\"uniprot\",\"identifier\":\"RASK_HUMAN\",\"description\":\"GTPase KRas\",\"organism\":\"Homo sapiens (Human)\",\"accession\":\"P01116\",\"taxid\":\"9606\"},\"motifs\":[{\"colour\":\"#00ffff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"1.3900\",\"type\":\"low_complexity\",\"start\":\"7\",\"end\":\"15\"},\"start\":7,\"end\":15,\"display\":false}]}]'); -INSERT INTO "pfam_graphics" ("UNIPROT_ACC","JSON_DATA") VALUES ('P01111','[{\"length\":\"189\",\"regions\":[{\"modelStart\":\"1\",\"modelEnd\":\"161\",\"colour\":\"#2dcf00\",\"endStyle\":\"jagged\",\"end\":\"165\",\"display\":true,\"startStyle\":\"curved\",\"aliEnd\":\"164\",\"modelLength\":\"162\",\"text\":\"Ras\",\"href\":\"/family/PF00071\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"2.7e-54\",\"description\":\"Ras family\",\"end\":\"165\",\"accession\":\"PF00071\",\"database\":\"pfam\",\"aliEnd\":\"164\",\"identifier\":\"Ras\",\"type\":\"Domain\",\"aliStart\":\"5\",\"start\":\"5\"},\"aliStart\":\"5\",\"start\":5}],\"markups\":[],\"metadata\":{\"database\":\"uniprot\",\"identifier\":\"RASN_HUMAN\",\"description\":\"GTPase NRas\",\"organism\":\"Homo sapiens (Human)\",\"accession\":\"P01111\",\"taxid\":\"9606\"},\"motifs\":[{\"colour\":\"#00ffff\",\"type\":\"low_complexity\",\"metadata\":{\"database\":\"seg\",\"score\":\"1.3900\",\"type\":\"low_complexity\",\"start\":\"7\",\"end\":\"15\"},\"start\":7,\"end\":15,\"display\":false}]}]'); -INSERT INTO "pfam_graphics" ("UNIPROT_ACC","JSON_DATA") VALUES ('Q9Y243','[{\"length\":\"479\",\"regions\":[{\"modelStart\":\"1\",\"modelEnd\":\"102\",\"colour\":\"#2dcf00\",\"endStyle\":\"jagged\",\"end\":107,\"display\":true,\"startStyle\":\"curved\",\"aliEnd\":\"105\",\"modelLength\":\"104\",\"text\":\"PH\",\"href\":\"/family/PF00169\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"3.7e-08\",\"description\":\"PH domain\",\"end\":\"107\",\"accession\":\"PF00169\",\"database\":\"pfam\",\"aliEnd\":\"105\",\"identifier\":\"PH\",\"type\":\"Domain\",\"aliStart\":\"6\",\"start\":\"6\"},\"aliStart\":\"6\",\"start\":6},{\"modelStart\":\"3\",\"modelEnd\":\"260\",\"colour\":\"#ff5353\",\"endStyle\":\"curved\",\"end\":\"405\",\"display\":true,\"startStyle\":\"jagged\",\"aliEnd\":\"405\",\"modelLength\":\"260\",\"text\":\"Pkinase\",\"href\":\"/family/PF00069\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"3.5e-72\",\"description\":\"Protein kinase domain\",\"end\":\"405\",\"accession\":\"PF00069\",\"database\":\"pfam\",\"aliEnd\":\"405\",\"identifier\":\"Pkinase\",\"type\":\"Domain\",\"aliStart\":\"150\",\"start\":\"148\"},\"aliStart\":\"150\",\"start\":\"148\"},{\"modelStart\":\"1\",\"modelEnd\":\"45\",\"colour\":\"#5b5bff\",\"endStyle\":\"jagged\",\"end\":\"476\",\"display\":true,\"startStyle\":\"curved\",\"aliEnd\":\"474\",\"modelLength\":\"48\",\"text\":\"Pkinase_C\",\"href\":\"/family/PF00433\",\"type\":\"pfama\",\"metadata\":{\"scoreName\":\"e-value\",\"score\":\"0.0012\",\"description\":\"Protein kinase C terminal domain\",\"end\":\"476\",\"accession\":\"PF00433\",\"database\":\"pfam\",\"aliEnd\":\"474\",\"identifier\":\"Pkinase_C\",\"type\":\"Family\",\"aliStart\":\"425\",\"start\":\"425\"},\"aliStart\":\"425\",\"start\":\"425\"}],\"markups\":[{\"lineColour\":\"#ff0000\",\"colour\":\"#aaaaaa\",\"end\":76,\"display\":true,\"v_align\":\"top\",\"metadata\":{\"database\":\"UniProt\",\"type\":\"disulphide\",\"start\":\"59\",\"end\":\"76\"},\"type\":\"disulphide\",\"start\":59},{\"lineColour\":\"#ff0000\",\"colour\":\"#aaaaaa\",\"end\":\"307\",\"display\":true,\"v_align\":\"top\",\"metadata\":{\"database\":\"UniProt\",\"type\":\"disulphide\",\"start\":\"293\",\"end\":\"307\"},\"type\":\"disulphide\",\"start\":\"293\"}],\"metadata\":{\"database\":\"uniprot\",\"identifier\":\"AKT3_HUMAN\",\"description\":\"RAC-gamma serine/threonine-protein kinase EC=2.7.11.1\",\"organism\":\"Homo sapiens (Human)\",\"accession\":\"Q9Y243\",\"taxid\":\"9606\"},\"motifs\":[{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"100\",\"end\":\"104\"},\"start\":100,\"end\":104,\"display\":false},{\"colour\":\"#cccccc\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"112\",\"end\":\"139\"},\"start\":116,\"end\":\"139\",\"display\":true},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"392\",\"end\":\"393\"},\"start\":\"392\",\"end\":\"393\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"438\",\"end\":\"439\"},\"start\":\"438\",\"end\":\"439\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"445\",\"end\":\"448\"},\"start\":\"445\",\"end\":\"448\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"450\",\"end\":\"461\"},\"start\":\"450\",\"end\":\"461\",\"display\":false},{\"colour\":\"#00ffff\",\"type\":\"disorder\",\"metadata\":{\"database\":\"IUPred\",\"type\":\"disorder\",\"start\":\"463\",\"end\":\"476\"},\"start\":\"463\",\"end\":\"476\",\"display\":false},{\"colour\":\"#32cd32\",\"type\":\"coiled_coil\",\"metadata\":{\"database\":\"ncoils\",\"type\":\"coiled_coil\",\"start\":\"95\",\"end\":\"115\"},\"start\":108,\"end\":115,\"display\":true}]}]'); - -- users INSERT INTO users (EMAIL,NAME,ENABLED) values ('jami@gmail.com','Jami Bax',1); INSERT INTO users (EMAIL,NAME,ENABLED) values ('Lonnie@openid.org','Lonnie Penaloza',0); diff --git a/test/integration/test_integration_test_oncokb_import.sh b/test/integration/test_integration_test_oncokb_import.sh index e50bd829e76..bd00a5d1b77 100755 --- a/test/integration/test_integration_test_oncokb_import.sh +++ b/test/integration/test_integration_test_oncokb_import.sh @@ -2,7 +2,6 @@ # exit when any of these fails set -e -export DOCKER_IMAGE_CBIOPORTAL=cbioportal/cbioportal:demo-rfc72-squash run_in_service() { service=$1 diff --git a/test/integration/test_load_study.sh b/test/integration/test_load_study.sh index 64dff5fd32c..dc06e64fadd 100755 --- a/test/integration/test_load_study.sh +++ b/test/integration/test_load_study.sh @@ -2,7 +2,6 @@ # exit when any of these fails set -e -export DOCKER_IMAGE_CBIOPORTAL=cbioportal/cbioportal:demo-rfc72-squash run_in_service() { service=$1 diff --git a/test/integration/test_update_oncokb.sh b/test/integration/test_update_oncokb.sh index 5fefb51a766..a3901571c2f 100755 --- a/test/integration/test_update_oncokb.sh +++ b/test/integration/test_update_oncokb.sh @@ -2,7 +2,6 @@ # exit when any of these fails set -e -export DOCKER_IMAGE_CBIOPORTAL=cbioportal/cbioportal:demo-rfc72-squash run_in_service() { service=$1 shift