Skip to content

Commit

Permalink
Sync Master with the Release branch (#229)
Browse files Browse the repository at this point in the history
* [ALS-5508] Dependabot dep bumps

- httpd
- Jackson
- deleted some commented out stuff

* [ALS-5612] Create stored procedure to create a user (#154)

* Add a new stored procedure to enable user creation

* Specific database Auth

* Update CreateUserWithRole stored procedure in auth DB

The stored procedure, CreateUserWithRole, in the 'auth' database has been updated to improve user creation. It now checks for existing users and roles, and generates a new UUID if needed. Additionally, it associates new users with roles if they exist.

* Rename CreateUserWithRole stored procedure file

* Add general metadata parameter to CreateUserWithRole procedure

* [ALS-5612] Updated stored procedure (#155)

* Add connectionSubPrefix to user creation stored procedure

* Refactor connection prefix manipulation in SQL procedure

* Update user creation stored procedure
The changes made address the process of user creation in the stored procedure. A new variable, @baseUUID, has been introduced for storing UUIDs during processing. Additionally, the preparation of @connectionSubPrefix has been adjusted to concatenate LONG_TERM_TOKEN with existing values instead of overriding them.

* Add PIC-SURE User role assignment in CreateUserWithRole procedure

Improved the CreateUserWithRole stored procedure in the auth-db. All new users are now automatically assigned the 'PIC-SURE User' role in addition to specific roles designated during account creation. This ensures all users have access to the base level of functionalities.

* [ALS-0000] Fix wiring issues in auth app.

* Java 21, Spring, code refactor and deploy as standalone container. (#163)

**Deployment and Regression Testing**:
The changes have been thoroughly regression tested and are currently live in the [Nhanes Production](https://nhanes.hms.harvard.edu/psamaui/login) environment.

**Java Version**:
- Updated to use Amazon Corretto Java 21.0.1.

**Dependencies**:
- Upgraded all dependencies to their latest versions, with Spring Boot updated to 3.2.4 and other Spring dependencies to 6.1.5.
- Removed all unused dependencies.
- Added new dependencies including Spring Data JPA, Spring Dev Tools, Spring Security, and Spring Web.

**Docker Configuration**:
- Introduced a development version for both Docker Compose and Dockerfile.
- Transitioned to a multi-stage Dockerfile where the application is built using Maven, eliminating the need for a JRE on the build server.
- Changed deployment from a WAR file on the PIC-SURE WildFly server to a standalone Docker container using Tomcat as the application server.

**Application Configuration**:
- Eliminated WildFly-specific configurations.
- Replaced `standalone.xml` with `application.properties` for managing application variables and configurations.
- Updated to use MySQL 8 connector.
- Defined unprotected routes in the `SecurityConfig.java`.
- Integrated application variables directly in classes using Spring's `@Value` annotation, removing the `JAXRSConfiguration` class.

**Controller and Service Layers**:
- Refactored `Services` that were functioning as controllers into true services, adding necessary `Controllers`.
- Renamed all `Controllers` to include the keyword 'Controller' and ensured all services contain 'Service' in their names.
- Controller Annotations:
  - `@API` -> `@Tag`
  - `@Path` -> `@RequestMapping`
  - `@ApiOperation` -> `@Operation`
  - `@Get`, `@Post`, `@Put`, `@Delete`, etc. -> `@GetMapping`, `@PostMapping`, `@PutMapping`, `@DeleteMapping`, etc.
  - `@RolesAllowed` -> `@Secured`
  - `@ApiParam` -> `@Parameter`
  - `@PathParam` -> `@PathParameter`
  - No annotation for request bodies -> `@RequestBody` required

**Services**:
- Separated business logic into a true service layer to improve organization and testability.
- Utilized the `@Service` annotation for Spring auto-wiring.
- Adopted `@Transactional` where necessary and removed the use of `BaseEntityService` in favor of Spring Data JPA.

**Repositories**:
- Transitioned all entity classes to use Spring Data JPA repositories, extending `JpaRepository`.

**Entities and Models**:
- Replaced `BaseEntity` with a local implementation to support Java 21.
- Added models like `TokenInspection` and `CustomUserDetails` for enhanced authentication processes.

**Enums and Utilities**:
- Introduced a `SecurityRoles` enum to centralize role management.
- Replaced outdated utility classes with `RestClientUtil`
- updated `JWTUtil` JWT handling with Java 21 compatible libraries.

**Filters and Unit Tests**:
- Updated `JWTFilter` to support Java 21, Spring Web, and Spring Security.
- Confirmed that all unit tests pass, with additional mocks implemented due to the transition to Spring Data JPA.
- Increased unit test line coverage from **11%** to **61%** and method coverage from **14%** to **89%** for the service layer. I have increased the number of unit test cases from 29 to 176.

* Merge Fence specific branch into release

### Build
- Created `Jenkinsfile.fence`, which is used by Jenkins to build and upload this application to S3.

### AccessRule
Merged both `AccessRule` entities.
- Added two `AccessRule.TypeNaming` constants: `ALL_CONTAINS_OR_EMPTY` and `ALL_CONTAINS_OR_EMPTY_IGNORE_CASE`.
- Migrated `subAccessRule` and `subAccessRuleParent` to a single `subAccessRule` property that uses a `@JoinTable` to represent the same relationship.
- Added a new migration script to update existing `AccessRule` tables to use the new `JoinTable`.

### AccessRuleService
Merged both `AccessRuleService` classes.
- Updated all logic to account for the two new `AccessRule.TypeNaming` constants.
- Refactored the AccessRule cache in the FENCE branch to use Spring's `@Cacheable` and `@CacheEvict`.

### AuthorizationService
Merged both `AuthorizationService` classes.
- Introduced a new property named `strictConnections`, which is assigned a comma-separated list of connection labels. These connections will be evaluated using a more strict authentication flow, requiring the user to have associated access rules and privileges. For non-strict connections, the user only needs associated privileges.
    - This approach may be revisited later. Standardizing on one approach is advisable.

### FenceAuthenticationService
- Removed the existing `FenceAuthenticationService` and replaced it with the version from the Fence-specific branch.
- Incorporated the most recent changes to Role, Privilege, AccessRule, and Fence Mapping into the `FenceAuthenticationService`, including the `FenceMappingUtility` class.

### Additional Authentication Services
- Added `Okta0AuthAuthenticationService`, `OpenAuthenticationService`, and `StudyAccessService` to the merged branch. These services previously existed only in the Fence branch.

### Controllers
- Refactored all service classes migrated from the Fence-specific branch to have associated `Controller` classes.

### Java 21 & Spring
- Refactored all classes migrated from the Fence-specific branch to accommodate Java 21, Spring Boot 3, and Spring 6.

### Unit Test
- Merged all unit tests from the Fence branch into related test classes or added them to the project. Ensured that no test changes were logically altered, providing confidence when merging and refactoring classes. The goal was to ensure no currently available test cases failed.

* Remove unnecessary configurations from Jenkinsfile

* Update logging level in Token and Authorization services

The logging level in both the TokenService and AuthorizationService has been changed from info to debug. This change helps to manage the verbosity of logs, ensuring that only crucial information is logged at the info level.

* Remove unnecessary logging

* [ALS-6567] Add classes for fence_mapping.json

Added three new model classes: BioDataCatalyst, StudyMetaData and IsHarmonizedDeserializer. These classes are used when parsing fence_mapping.json.

* Update FenceMappingUtility with new model classes

Updated the FenceMappingUtility.java and associated test cases to use new model classes: BioDataCatalyst and StudyMetaData. Additionally, roles are now created after the application Context is initialized.

* Improve FENCEAuthenticationService with additional checks and code refactoring

The code has been modified to include an additional check in FENCEAuthenticationService to ensure that FENCEMapping is not empty before creating access rules. This will prevent unnecessary errors and exception handling.

* Update persistAll method to return list of roles

The persistAll method in RoleService.java has been revised to return a list of Role objects after saving them. This change is also reflected in FENCEAuthenticationService.java where the returned list of new roles is now properly assigned to newRoles.

* [ALS-6398] Enable secure and http-only flags for session cookies

* [ALS-6103] Architectural changes to support multiple auth providers (#183)

- Removed `OpenAuthenticationController`, `OktaAuthenticationController`, and `AuthController`.

- Created the `AuthenticationService` interface. All authentication service classes **MUST** implement this interface. This interface contains three methods: `authenticate`, `getProvider()`, and `isEnabled()`.
  - `authenticate`: Implements the specific authentication logic for each authentication service.
  - `getProvider`: Returns the name of the provider, e.g., `fence`, `open`, `auth0`, etc. These values must correspond to the `idpProvider` value in the authentication controller path `/auth/authentication/{idpProvider}`. This value is used to look up the correct authentication service in the `AuthenticationServiceRegistry` class.
  - `isEnabled`: Returns `true` or `false` based on the corresponding `application.properties` value.

- Created the `AuthenticationServiceRegistry`. This service registry maintains a map of all enabled `AuthenticationService` services and provides a `getAuthenticationService` method that returns an `AuthenticationService` based on the provider string.

- Created the `AuthenticationController`. This controller uses the `AuthenticationServiceRegistry` to dynamically delegate authentication to the correct `AuthenticationService` based on the `{idpProvider}` path variable.

* [ALS-6103] Update StudyAccessController with new annotations

Added 'RolesAllowed' and 'RequestMapping' annotations to the StudyAccessController. The 'RolesAllowed' annotation replaces the 'Secured' one to specify authorized roles. The 'RequestMapping' annotation is added to specify the path for accessing study data.

* [ALS-6103] Update StudyAccessController with new annotations (#184)

Added 'RolesAllowed' and 'RequestMapping' annotations to the StudyAccessController. The 'RolesAllowed' annotation replaces the 'Secured' one to specify authorized roles. The 'RequestMapping' annotation is added to specify the path for accessing study data.

* Resolve leading whitespace error programmatically (#185)

* [Hotfix][ALS-6861] BDC Auth showing as down on the BDC Graphana dashboard  (#186)

* [ALS-6861] Optimize logging and enhance routing flexibility

* [ALS-6861] Optimize logging and enhance routing flexibility

* [ALS-6861] Remove logging

* Update AuthorizationService (#187)

* Update AuthorizationService

Open access does not currently assign a connection to users. We should change this in the future, but for now we will handle the case.

* Refactor open access role handling in UserService

The revision refactors how open access roles are handled in UserService.java. A condition was added to check if the user's roles are null before assigning a new HashSet, thus improving code robustness. Instead of setting the roles directly, the role is now added to the user's existing roles, ensuring preservation of any pre-existing roles.

* [ALS-6882] Fix migrator by dropping constraint

* Remove AR drop

* [CHORE] - Switch fetch type to EAGER

* Update Dockerfile

copies in maven settings.xml

* Update Dockerfile

move maven settings copy before mvn command...

* Implement RAS Authentication Provider (#195)

- Create `OktaAuthenticationService` by extracting generic OKTA authentication code.
- Create & Implement RASAuthenticationService and RASAuthenticationServiceTest.
- Create & Implement RASPassportService and RASPassportServiceTest.
-  Implement RAS Passport handling and polling.
    - Add new enum for potential passport validation responses. This is used to ensure all potential return values are handled with in a switch statement.
- Add model for RAS Passport and RAS Visas.
- Add `Passport` property to User entity.
    - Includes a corresponding migration script to add new column to database.
- Add new methods to the JWTUtil class to assist with decoding and parsing RAS Passports which use a JWT format.
- Included SessionService for session management with caching support.

* Revert "Update Dockerfile"

This reverts commit 67be2c6.

* Revert "Update Dockerfile"

This reverts commit 36ad515.

* [ALS-7197] BDC Auth access: User able to access data (#203)

* - The clinical query template has been updated to include the `parentAccessField` in the fields section. The `parentAccessionField` value is now set to `\\\\_Parent Study Accession with Subject ID\\\\`.

- The `TOPMED+PARENT` access rule, associated with clinical privileges, has been fixed. The rule previously had misconfigured `subAccessRules` and `gates`:
    - The `TOPMED_CONSENT` gate consent rule was incorrectly set to `IS_EMPTY` instead of `IS_NOT_EMPTY`, causing queries to be erroneously rejected, even when the `"categoryFilters": "\\_topmed_consents\\"` section was correctly included in the query.
    - A missing `subAccessRule` named `ALLOW_TOPMED_CONSENT` was added. This rule ensures that all required consents are present in the `\\_topmed_consents\\` section of the query template.
    - A new method, `configureClinicalAccessRuleWithPhenoSubRule`, was added to `AccessRuleService`. This method contains the configuration for this access rule.

- Previously, there were many unassociated access rules. All access rules are now correctly linked to other rules and privileges. In Spring Boot, any entity property defining a parent-child relationship must use the `cascade = CascadeType.ALL` option in the `@ManyToOne` or `@ManyToMany` annotations to ensure updates to the parent or child entities on save.

- A new role, `MANUAL_ROLE_NAMED_DATASET`, has been assigned to all BDC users. This role grants users access to the `/named/dataset/`, `/named/dataset/{uuid}`, and `/query/{uuid}/metadata` endpoints. The role, along with its privilege and rule definition, is now part of the BDC infrastructure.

- The `createPhoneTypeSubRule` method now correctly removes double-escaped characters. For example, a concept path formatted as `\\\\phs000xxx\\\\` is now converted to `\\phs000xxx\\`.

- The `upsertConsentGate` method now properly escapes backslashes in rules.

- The `extractAndCheckRule` method now correctly evaluates access rules that need to check map nodes. When using JsonPath to retrieve a node value, it is naturally converted into a list. This list is now converted into a Map for key checking.

- When evaluating `subAccessRules` for a given rule, the rules must first be merged before evaluation. Since sub access rules may overlap with other rules, the method `preProcessARBySortedKeys` is used to handle the merging process.

- The `pic-sure-auth-micro-app` was originally designed with an ephemeral database. With each deployment, all roles, privileges, and access rules were re-created. This provided an opportunity to add new allowed query types and standard access rules. Now that our database is persisted, there was no mechanism to add new allowed query types or standard access rules. A new method has been added to `PrivilegeService` named `updateAllPrivilegesOnStartup`.
    - This method updates all privileges to include all current standard access rules. Any standard access rules that need to be removed from a privilege must be handled via a migration script.
    - The method also updates all allowed query types. All existing allowed query types are removed from each `access_rule` that currently has allowed query types as `subAccessRules`. Once these are removed, all currently defined allowed query types are added to the `access_rule`, enabling the addition or removal of allowed query types without needing migration scripts.

* Add transactional annotation to PrivilegeRepository

* Change event listener and improve privilege update logic

* Refactor privilege update method to avoid transactional query

Replaced the custom query with direct calls to add access rules and save privileges. This simplifies the code and utilizes existing save method, ensuring transactional consistency.

* Fix sub-access rule addition in PrivilegeService

* Refactor role name constants to uppercase

* Set logging level to DEBUG for auth service implementation

Changed the logging level for `edu.harvard.hms.dbmi.avillach.auth.service.impl` from INFO to DEBUG to facilitate detailed debugging. This will help in tracking down issues more effectively during development and troubleshooting.

* Switch logging level from DEBUG to TRACE in AccessRuleService

Changed the logging level from DEBUG to TRACE for specific methods in AccessRuleService to reduce the verbosity of the application logs. This will make debugging more efficient by including detailed logs specific to fine-grain debugging levels without cluttering higher-level log outputs.

* Restrict logging to denied access attempts

Refactor log statement in AuthorizationService to log only when access is denied. This change reduces unnecessary log entries for granted access, improving log readability and performance.

* Fix double backslash handling in Topmed access rule generation

Address an issue where double backslashes in the concept path were not appropriately converted, causing potential mismatches in rule text generation. This ensures consistency by replacing all instances of `\\\\` with `\\` before forming the rule text.

* Lower logging level in evaluateAccessRule method

Changed log level from debug to trace for initial access rule evaluation steps. This change reduces verbosity in the logs, helping to focus on more critical debug information.

* Update pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/service/impl/authorization/AuthorizationService.java

* Enhance logging and configuration (#207)

Updated logging statements to include user roles upon login in both RAS and FENCE authentication services. Parameterized logging levels in the application properties file for more flexible runtime configuration.

* ALS-7306: Add expected result type auth for PFB (#208)

* Fix token validation logic for long-term tokens (#209)

* Fix token validation logic for long-term tokens

* Fix token inspection logic and add logging for token refresh

* Add long-term token check in isAuthorized method (#210)

This commit adds a new parameter `isLongTermToken` to the `isAuthorized` method in the `AuthorizationService` class. It updates the `TokenService` and several test cases to accommodate this change, ensuring that long-term tokens bypass the session expiration check.

* Update Jenkinsfile to use uppercase for LATEST_TAG (#212)

Changed the value of LATEST_TAG from "latest" to "LATEST" to standardize the convention used for tagging. This ensures consistency across different environments and avoids potential issues with mismatched tag names.

* [ALS-6921] Implement Open Access in PSAMA (#211)

- The logout handler now returns a `200 OK` status upon success.
- Added a new `OpenAccessController` that includes a single `open/validate` endpoint.
- `JWTFilter` now permits the `open/validate` endpoint when using an application token.
- Added a new `record` named `EvaluateAccessRuleResult`, which is returned from `passesAccessRuleEvaluation` after evaluating the access rules against the query.
- Introduced a new method named `openAccessRequestIsValid`, which is used to validate open access requests.
- Updated the callback URLs to use the new UI path `login/loading/`.
- Removed `OpenAuthenticationService` and `OpenAuthenticationServiceTest` as they are no longer needed.
- A new open access query template is returned for request that do not have an associated `uuid` or `user`.

* Add deployment toggle to Jenkinsfile (#213)

* Fix type for DEPLOY parameter in Jenkinsfile (#214)

* Change Jenkins Parameter (#215)

* Fix type for DEPLOY parameter in Jenkinsfile

* Add logout endpoint and improve token validation (#217)

Allow the "/logout" endpoint to be accessed without authentication to facilitate user sign-out. Additionally, enhance the logout handler by adding checks for token prefix and blank token to improve robustness.

* Check for open access enabled (#218)

* Add AR_DICTIONARY_REQUESTS (#219)

* [ALS-6880] HttpClient with proxy

* [ALS-6880] SLF4J dep issues

* restTemplate connection refactoring

* refactor to explicitly set proxy

* Fix for error:
400 Bad Request: "invalid json"

* [CHORE] int friendly default for RestClientConf

* Update Dockerfile

move maven settings copy before mvn command...

* Add Javadoc comments to model classes (#223)

Enhance code documentation by adding Javadoc comments to Ga4ghVisaV1, Ga4ghPassportV1, RasDbgapPermission, Passport, and User classes. These comments provide a clearer understanding of the purpose and structure of each class.

* [CHORE] This is not an error

* [ALS-7575] Add cache inspection and eviction services (#222)

[ALS-7575] Added new endpoints for cache inspection and introduced CacheEvictionService to handle cache eviction for users. Security configuration was updated to allow access to cache endpoints, and several services were modified to utilize the new cache eviction mechanisms.

* [ALS-7554] User should not be able to search without a valid token (#225)

* Set token 'active' field to false on invalid token scenarios
Ensure the 'active' field in tokenInspection is marked false whenever a token is invalid or user not found. This improves the clarity and consistency of token status checks throughout the service.

* Remove custom key generator from cache eviction
Removed the custom key generator from cache eviction in AccessRuleService for streamlined annotation usage. Added null and blank subject checks in CacheEvictionService to prevent errors, and removed unnecessary blank line in FENCEAuthenticationService.

---------

Co-authored-by: Luke Sikina <[email protected]>
Co-authored-by: Jeremy Nix <[email protected]>
Co-authored-by: Luke Sikina <[email protected]>
Co-authored-by: ramari16 <[email protected]>
  • Loading branch information
5 people authored Oct 23, 2024
1 parent 288c91e commit a0e56cc
Show file tree
Hide file tree
Showing 198 changed files with 15,610 additions and 9,253 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,6 @@ pic-sure-auth-services.war.deployed
*.war
*.deployed
*.failed

.m2
!.m2/README.md
4 changes: 4 additions & 0 deletions .m2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
The .m2 dir is used to pass proxy args to Jenkins
for environments that access the outside internet via
an HTTP proxy

41 changes: 41 additions & 0 deletions Jenkinsfile.fence
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
pipeline {
agent any

parameters {
string(name: 'DOCKER_REGISTRY', description: 'Docker registry URL (e.g., ECR URL)', defaultValue: 'hms-dbmi')
string(name: 'REPOSITORY_NAME', description: 'Docker repository name', defaultValue: 'psama')
string(name: 'DATASOURCE_URL', description: 'Datasource URL', defaultValue: '${database_host_address}')
string(name: 'DATASOURCE_USERNAME', description: 'Datasource username', defaultValue: '${database_app_user_secret_name}')
string(name: 'STACK_SPECIFIC_APPLICATION_ID', description: 'Application ID for base query', defaultValue: '${application_id_for_base_query}')
}

environment {
DOCKER_BUILD_ARGS = "-f ./pic-sure-auth-services/bdc.Dockerfile"
GIT_BRANCH_SHORT = sh(script: 'echo ${GIT_BRANCH} | cut -d "/" -f 2', returnStdout: true).trim()
GIT_COMMIT_SHORT = sh(script: 'echo ${GIT_COMMIT} | cut -c1-7', returnStdout: true).trim()
IMAGE_TAG = "${GIT_BRANCH_SHORT}_${GIT_COMMIT_SHORT}"
LATEST_TAG = "latest"
}

stages {
stage('Build Docker Image') {
steps {
script {
// Define the build args
def buildArgs = " --build-arg DATASOURCE_URL=${env.DATASOURCE_URL} " +
" --build-arg DATASOURCE_USERNAME=${env.DATASOURCE_USERNAME} " +
" --build-arg STACK_SPECIFIC_APPLICATION_ID=${env.STACK_SPECIFIC_APPLICATION_ID} "

sh "docker build ${DOCKER_BUILD_ARGS} ${buildArgs} -t ${params.DOCKER_REGISTRY}/${params.REPOSITORY_NAME}:${IMAGE_TAG} ."
sh "docker tag ${params.DOCKER_REGISTRY}/${params.REPOSITORY_NAME}:${IMAGE_TAG} ${params.DOCKER_REGISTRY}/${params.REPOSITORY_NAME}:${LATEST_TAG}"
}
}
}
stage('Deploy Docker Image') {
steps {
sh "docker save ${params.DOCKER_REGISTRY}/${params.REPOSITORY_NAME}:${LATEST_TAG} | gzip > psama.tar.gz"
sh "aws s3 --sse=AES256 cp psama.tar.gz s3://$S3_BUCKET_NAME/releases/psama/psama.tar.gz"
}
}
}
}
12 changes: 12 additions & 0 deletions cache.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# This class can be used to interact with the CacheController in the PSAMA API
# The CacheController must be enable in the application.properties file
# You can enable it by setting the following property:
# app.cache.inspect.enabled=true
# If you are using a environment variable to set the property, you can set it like this:
# CACHE_INSPECT_ENABLED=true

### GET /cache - Get a list of all caches in the application
GET https://dev.picsure.biodatacatalyst.nhlbi.nih.gov/psama/cache

### GET /cache/{cacheName} - Get the contents of a specific cache
GET https://dev.picsure.biodatacatalyst.nhlbi.nih.gov/psama/cache/mergedRulesCache
4 changes: 4 additions & 0 deletions config/psama/bdc/psama-db-config.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.datasource.driver-class-name=com.amazonaws.secretsmanager.sql.AWSSecretsManagerMySQLDriver
spring.datasource.url=jdbc-secretsmanager:mysql://${DATASOURCE_URL}/auth?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&autoReconnectForPools=true
spring.datasource.username=${DATASOURCE_USERNAME}
32 changes: 32 additions & 0 deletions config/psama/psama.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# This is a template file that can be used to configure the application. Pass this to the dockerfile and
# the application will be configured with the values provided in this file.

# These properties are used to configure our applications JWT token.
# The JWT token is used to authenticate the user and authorize them to access the application
# after initial login.
APPLICATION_CLIENT_SECRET=
APPLICATION_CLIENT_SECRET_IS_BASE_64=false
STACK_SPECIFIC_APPLICATION_ID=

# Fence IDP Configuration
FENCE_IDP_PROVIDER_IS_ENABLED=false
FENCE_CLIENT_ID=
FENCE_CLIENT_SECRET=
FENCE_IDP_PROVIDER_URI=

# AIM AHEAD Authorized Access (A4) OKTA IDP Configuration
A4_OKTA_IDP_PROVIDER_IS_ENABLED=false
A4_OKTA_CLIENT_SECRET=
A4_OKTA_CLIENT_ID=
A4_OKTA_CONNECTION_ID=
A4_OKTA_IDP_PROVIDER_URI=

# Auth0 IDP Configuration (Generally, this is used for the All-In-One and Authorized Access)
AUTH0_IDP_PROVIDER_IS_ENABLED=false
AUTH0_HOST=
AUTH0_DENIED_EMAIL_ENABLED=

# Open Access IDP Configuration
OPEN_IDP_PROVIDER_IS_ENABLED=false

SYSTEM_NAME=PIC-SURE BioDataCatalyst
52 changes: 52 additions & 0 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
version: '3.8'
services:
pic-sure-auth-service:
build:
context: .
dockerfile: ./pic-sure-auth-services/dev.Dockerfile
environment:
JAVA_OPTS: "-Xmx1024m -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"
# Note: To use this you will need to set ENVIRONMENT variables for the application.properties
ports:
- "8090:8090" # Application port
- "5005:5005" # Debug port
depends_on:
auth-flyway:
condition: service_started

picsure-db:
build:
context: ./pic-sure-auth-db/
dockerfile: Dockerfile
environment:
MYSQL_DATABASE: auth
MYSQL_ROOT_PASSWORD: password
ports:
- "3306:3306" # MySQL port
command:
- --default-authentication-plugin=mysql_native_password # Required for MySQL 8.0
healthcheck:
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5

auth-flyway:
image: flyway/flyway:latest
volumes:
- ./pic-sure-auth-db/db/sql:/flyway/sql
# linux/amd64
platform: linux/amd64
environment:
- FLYWAY_URL=jdbc:mysql://picsure-db:3306/auth?useSSL=false
- FLYWAY_USER=root
- FLYWAY_PASSWORD=password
- FLYWAY_SCHEMAS=auth
- FLYWAY_LOCATIONS=filesystem:/flyway/sql
- FLYWAY_IGNORE_MISSING_MIGRATIONS=true
- FLYWAY_BASELINE_ON_MIGRATE=true
command:
- migrate
depends_on:
picsure-db:
condition: service_healthy
48 changes: 48 additions & 0 deletions jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
pipeline {
agent any

parameters {
string(name: 'DOCKER_REGISTRY', description: 'Docker registry URL (e.g., ECR URL)', defaultValue: 'hms-dbmi')
string(name: 'REPOSITORY_NAME', description: 'Docker repository name', defaultValue: 'psama')
booleanParam(name: 'DEPLOY', description: 'Deploy the image to the registry', defaultValue: true)
}

environment {
DOCKER_BUILD_ARGS = "-f ./pic-sure-auth-services/Dockerfile --build-arg http_proxy=$http_proxy --build-arg https_proxy=$http_proxy --build-arg no_proxy=\"$no_proxy\" --build-arg HTTP_PROXY=$http_proxy --build-arg HTTPS_PROXY=$http_proxy --build-arg NO_PROXY=\"$no_proxy\""
GIT_BRANCH_SHORT = sh(script: 'echo ${GIT_BRANCH} | cut -d "/" -f 2', returnStdout: true).trim()
GIT_COMMIT_SHORT = sh(script: 'echo ${GIT_COMMIT} | cut -c1-7', returnStdout: true).trim()
IMAGE_TAG = "${GIT_BRANCH_SHORT}_${GIT_COMMIT_SHORT}"
LATEST_TAG = "LATEST"
EMAIL_TEMPLATE_VOLUME="-v $DOCKER_CONFIG_DIR/wildfly/emailTemplates:/opt/jboss/wildfly/standalone/configuration/emailTemplates "
TRUSTSTORE_VOLUME="-v $DOCKER_CONFIG_DIR/wildfly/application.truststore:/opt/jboss/wildfly/standalone/configuration/application.truststore"
PSAMA_OPTS="-Xms1g -Xmx2g -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true"
TRUSTSTORE_JAVA_OPTS="-Djavax.net.ssl.trustStore=/opt/jboss/wildfly/standalone/configuration/application.truststore -Djavax.net.ssl.trustStorePassword=password"
}

stages {
stage('build') {
steps {
sh "docker build ${DOCKER_BUILD_ARGS} -t ${params.DOCKER_REGISTRY}/${params.REPOSITORY_NAME}:${IMAGE_TAG} ."
sh "docker tag ${params.DOCKER_REGISTRY}/${params.REPOSITORY_NAME}:${IMAGE_TAG} ${params.DOCKER_REGISTRY}/${params.REPOSITORY_NAME}:${LATEST_TAG}"
}
}
stage('deploy') {
steps {
script {
env.PROXY_OPTS = env.PROXY_OPTS == null ?: ''
if (params.DEPLOY) {
sh "docker stop psama || true"
sh "docker rm psama || true"
sh """docker run --name=psama --restart always \
--network=picsure \
--env-file /usr/local/docker-config/psama/.env \
$EMAIL_TEMPLATE_VOLUME \
$TRUSTSTORE_VOLUME \
-e JAVA_OPTS="$PSAMA_OPTS $TRUSTSTORE_JAVA_OPTS" \
-d ${params.DOCKER_REGISTRY}/${params.REPOSITORY_NAME}:${IMAGE_TAG}"""
}
}
}
}
}
}
2 changes: 1 addition & 1 deletion pic-sure-auth-db/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM mysql:5.7.24
FROM mysql:8.2.0

RUN mkdir /tempsql/
COPY db/picsure-auth-dump-initial.sql /tempsql/picsure-auth-dump-initial.sql
Expand Down
43 changes: 43 additions & 0 deletions pic-sure-auth-db/db/sql/V4__ADD_CREATE_USER_STORED_PROCEDURE.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
USE `auth`;

DROP PROCEDURE IF EXISTS CreateUserWithRole;
DELIMITER //
CREATE PROCEDURE CreateUserWithRole(
IN user_email VARCHAR(255),
IN connection_id VARCHAR(255),
IN role_name VARCHAR(255),
IN user_general_metadata varchar(255)
)
BEGIN
-- Attempt to retrieve the UUIDs for the user and role based on the provided information
SELECT @userUUID := uuid FROM auth.user WHERE email = user_email AND connectionId = connection_id;
SELECT @roleUUID := uuid FROM auth.role WHERE name = role_name;
SELECT @picsureUserRoleId := uuid FROM auth.role WHERE name = 'PIC-SURE User';

-- If the user does not exist, create a new user entry
IF @userUUID IS NULL THEN
set @baseUUID = UUID();
-- Generate a new UUID for the user
SET @userUUID = UNHEX(REPLACE(@baseUUID, '-', ''));
-- Retrieve the UUID for the connection
SELECT @connectionUUID := uuid FROM auth.connection WHERE id = connection_id;
SELECT @connectionSubPrefix := subPrefix FROM auth.connection WHERE id = connection_id;
-- Insert the new user record into the user table
INSERT INTO auth.user (uuid, general_metadata, acceptedTOS, connectionId, email, matched, subject, is_active,
long_term_token)
VALUES (@userUUID, user_general_metadata, CURRENT_TIMESTAMP, @connectionUUID, user_email, 0,
concat(@connectionSubPrefix, REPLACE(@baseUUID, '-', '')), 1, NULL);
END IF;

-- If the role exists, associate the user with the role
IF @roleUUID IS NOT NULL THEN
INSERT INTO auth.user_role (user_id, role_id) VALUES (@userUUID, @roleUUID);
END IF;

-- If the role is not PIC-SURE User, associate the user with the PIC-SURE User role as well
-- All users must have the PIC-SURE User role
IF @roleUUID IS NOT NULL AND @roleUUID != @picsureUserRoleId THEN
INSERT INTO auth.user_role (user_id, role_id) VALUES (@userUUID, @picsureUserRoleId);
END IF;
END//
DELIMITER ;
31 changes: 31 additions & 0 deletions pic-sure-auth-db/db/sql/V5__MIGRATE_TO_ACCESSRULE_JOINTABLE.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# When merging the FENCE (Also consider the BDC specific) specific pic-sure-auth-micro-app and the more general
# pic-sure-auth-micro-app, we need to remove the circular dependency between the access_rule table and itself.
# We could have supported both, but the same functionality is already supported by the accessRule_subRule join table.
# This script will remove the circular dependency and replace it with a reference to the join table.

-- Step 1: Create the join table
--
-- Table structure for table `accessRule_subRule`
--
CREATE TABLE `accessRule_subRule`
(
`accessRule_id` binary(16) NOT NULL,
`subRule_id` binary(16) NOT NULL,
PRIMARY KEY (`accessRule_id`, `subRule_id`),
KEY (`subRule_id`),
CONSTRAINT FOREIGN KEY (`subRule_id`) REFERENCES `access_rule` (`uuid`),
CONSTRAINT FOREIGN KEY (`accessRule_id`) REFERENCES `access_rule` (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

-- Step 2: Insert data from the circular dependency into the join table
INSERT INTO accessRule_subRule (accessRule_id, subRule_id)
SELECT ar.uuid, ar.subAccessRuleParent_uuid
FROM access_rule ar
WHERE ar.subAccessRuleParent_uuid IS NOT NULL;

-- Step 3: Update references in the original table to point to the join table
UPDATE access_rule ar
JOIN accessRule_subRule ars ON ars.accessRule_id = ar.uuid
SET ar.subAccessRuleParent_uuid = NULL; -- Remove circular dependency reference so it can be dropped

-- Step 4: Drop the column from the original table
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# We have migrated our naming convention away from "FENCE_" to a more generalized "MANAGED_".

-- Update roles table
UPDATE role
SET name = REPLACE(name, 'FENCE', 'MANAGED')
WHERE name LIKE '%FENCE%';

UPDATE role
SET description = REPLACE(description, 'FENCE', 'MANAGED')
WHERE description LIKE '%FENCE%';

-- Update privileges table
UPDATE privilege
SET name = REPLACE(name, 'FENCE', 'MANAGED')
WHERE name LIKE '%FENCE%';

UPDATE privilege
SET description = REPLACE(description, 'FENCE', 'MANAGED')
WHERE description LIKE '%FENCE%';

-- Update access rules table
UPDATE access_rule
SET name = REPLACE(name, 'FENCE', 'MANAGED')
WHERE name LIKE '%FENCE%';

UPDATE access_rule
SET description = REPLACE(description, 'FENCE', 'MANAGED')
WHERE description LIKE '%FENCE%';
1 change: 1 addition & 0 deletions pic-sure-auth-db/db/sql/V7__Add_Passport_User_Col.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE user ADD COLUMN passport TEXT;
48 changes: 17 additions & 31 deletions pic-sure-auth-services/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,40 +1,26 @@
FROM jboss/wildfly:17.0.0.Final AS production
FROM maven:3.9.6-amazoncorretto-21 as build

# TODO: It'd be nice if wildfly used alpine -Andre
# Copy the source code into the container
COPY ./ /app

LABEL maintainer="[email protected]"
# Pull in global maven settings
COPY ./.m2/*.xml /root/.m2/

# mysql database
ENV AUTH_DB_CONNECTION_USER root
ENV AUTH_MYSQLADDRESS localhost
ENV AUTH_DB_PORT 3306
ENV AUTH_MYSQLPASS password
# Change the working directory
WORKDIR /app

# JWT Token
ENV AUTH_CLIENT_SECRET secret
ENV AUTH_USER_ID_CLAIM sub
# Build the jar
RUN mvn clean install -DskipTests

# root required to create default scratch directory - Andre
USER root
FROM amazoncorretto:21.0.1-alpine3.18

# Add certs for AWS to trust store
COPY aws_certs/certificate.der certificate.der
RUN keytool -noprompt -import -alias root_cert -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit -file certificate.der
# Copy jar and access token from maven build
COPY --from=build /app/pic-sure-auth-services/target/pic-sure-auth-services.jar /pic-sure-auth-service.jar

# copy modules
COPY target/modules/system/layers/base/com/sql/mysql/main/* /modules/
COPY src/main/resources/emailTemplates/accessEmail.mustache /usr/local/share/applications/
# Copy the AWS certificate
COPY pic-sure-auth-services/aws_certs/certificate.der /certificate.der

# install modules
RUN wildfly/bin/jboss-cli.sh --command="module add --name=com.sql.mysql \
--resources=/modules/mysql-connector-java-5.1.38.jar --dependencies=javax.api"
# Import the certificate into the Java trust store
RUN keytool -noprompt -import -alias aws_cert -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit -file /certificate.der

# Copy standalone.xml
COPY src/main/resources/wildfly-configuration/standalone.xml wildfly/standalone/configuration/

# Copy war file
COPY target/pic-sure-auth-services.war wildfly/standalone/deployments/pic-sure-auth-services.war

#USER jboss

ENTRYPOINT ["/opt/jboss/wildfly/bin/standalone.sh", "-b", "0.0.0.0"]
ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar /pic-sure-auth-service.jar"]
Loading

0 comments on commit a0e56cc

Please sign in to comment.