diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..651dcbb7d --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,91 @@ +name: build + +on: + workflow_call: + inputs: + environment: + required: true + type: string + module: + required: true + type: string + workflow_dispatch: + inputs: + environment: + required: true + type: choice + options: + - dev + - test + module: + required: true + type: choice + options: + - api + - worker + +jobs: + build: + runs-on: self-hosted + + env: + ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true + AWS_REGION: ${{ vars.AWS_REGION }} + DEPLOYMENT_ENV: ${{ vars[format('{0}_DEPLOYMENT_ENV', inputs.environment)] }} + + steps: + - name: Checkout Code + uses: actions/checkout@v3 + + - name: Setup Java + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: '17' + + - name: Install Maven 3.6.3 + run: | + export PATH="$PATH:/opt/maven/bin" + echo "PATH=$PATH" >> $GITHUB_ENV + if mvn -v; then echo "Maven already installed" && exit 0; else echo "Installing Maven"; fi + tmpdir="$(mktemp -d)" + curl -LsS https://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz | tar xzf - -C "$tmpdir" + sudo rm -rf /opt/maven + sudo mv "$tmpdir/apache-maven-3.6.3" /opt/maven + + - name: Set env vars from AWS params in BCDA management account + uses: cmsgov/ab2d-bcda-dpc-platform/actions/aws-params-env-action@main + with: + params: | + ARTIFACTORY_URL=/artifactory/url + ARTIFACTORY_USER=/artifactory/user + ARTIFACTORY_PASSWORD=/artifactory/password + + - name: Build package + run: mvn -U clean package -s settings.xml -DskipTests -Dusername="${ARTIFACTORY_USER}" -Dpassword="${ARTIFACTORY_PASSWORD}" -Drepository_url="${ARTIFACTORY_URL}" + + - name: Assume role in AB2D Management account + uses: aws-actions/configure-aws-credentials@v3 + with: + aws-region: ${{ vars.AWS_REGION }} + role-to-assume: arn:aws:iam::${{ secrets.MGMT_ACCOUNT_ID }}:role/delegatedadmin/developer/ab2d-mgmt-github-actions + + - name: Build image and push to ECR + working-directory: ./${{ inputs.module }} + run: | + ECR_REPO_DOMAIN="${{ secrets.MGMT_ACCOUNT_ID }}.dkr.ecr.$AWS_REGION.amazonaws.com" + aws ecr get-login-password | docker login --username AWS --password-stdin "$ECR_REPO_DOMAIN" + ECR_REPO_URI="$ECR_REPO_DOMAIN/ab2d_${{ inputs.module }}" + SHA_SHORT=$(git rev-parse --short HEAD) + echo "Building image for commit sha $SHA_SHORT" + docker build \ + -t "${ECR_REPO_URI}:ab2d-${DEPLOYMENT_ENV}-$SHA_SHORT" \ + -t "${ECR_REPO_URI}:ab2d-${DEPLOYMENT_ENV}-latest" . + + # Push to special tag for promotion if this is run on a push to main + if [ "$GITHUB_REF" == "refs/heads/main" ]; then + docker tag $ECR_REPO_URI:ab2d-$DEPLOYMENT_ENV-$SHA_SHORT $ECR_REPO_URI:main-$SHA_SHORT + fi + + echo "Pushing image" + docker push "${ECR_REPO_URI}" --all-tags diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 000000000..22df77018 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,49 @@ +name: deploy + +on: + workflow_call: + inputs: + environment: + required: true + type: string + module: + required: true + type: string + workflow_dispatch: + inputs: + environment: + required: true + type: choice + options: + - dev + - test + - sbx + - prod + - prod_test + module: + required: true + type: choice + options: + - api + - worker + +jobs: + deploy: + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + steps: + - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 + env: + ACCOUNT: ${{ inputs.environment == 'prod_test' && 'prod' || inputs.environment }} + with: + aws-region: ${{ vars.AWS_REGION }} + role-to-assume: arn:aws:iam::${{ secrets[format('{0}_ACCOUNT_ID', env.ACCOUNT)] }}:role/delegatedadmin/developer/ab2d-${{ env.ACCOUNT }}-github-actions + - name: Deploy ECS service to run on latest image in ECR + env: + SERVICE_NAME: ab2d-${{ vars[format('{0}_DEPLOYMENT_ENV', inputs.environment)] }}-${{ inputs.module }} + run: | + echo "Deploying service $SERVICE_NAME" + aws ecs update-service --cluster "$SERVICE_NAME" --service "$SERVICE_NAME" --force-new-deployment > /dev/null + aws ecs wait services-stable --cluster "$SERVICE_NAME" --services "$SERVICE_NAME" diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index 285e476cd..fa1e9326b 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -1,13 +1,25 @@ name: end-to-end tests on: - pull_request: workflow_call: + inputs: + environment: + required: true + type: string workflow_dispatch: # Allow manual trigger + inputs: + environment: + required: true + type: choice + options: + - dev + - test + - sbx + default: test -# Ensure we have only one e2e test running at a time +# Ensure we have only one e2e test running at a time in each environment concurrency: - group: e2e-test + group: ${{ inputs.environment }}-e2e-test jobs: test: @@ -39,7 +51,7 @@ jobs: sudo rm -rf /opt/maven sudo mv "$tmpdir/apache-maven-3.6.3" /opt/maven - - name: Set env vars from AWS params in management account + - name: Set env vars from AWS params in BCDA management account uses: cmsgov/ab2d-bcda-dpc-platform/actions/aws-params-env-action@main env: AWS_REGION: ${{ vars.AWS_REGION }} @@ -49,13 +61,13 @@ jobs: ARTIFACTORY_USER=/artifactory/user ARTIFACTORY_PASSWORD=/artifactory/password - - name: Assume role in AB2D impl account + - name: Assume role in AB2D account for this environment uses: aws-actions/configure-aws-credentials@v3 with: aws-region: ${{ vars.AWS_REGION }} - role-to-assume: arn:aws:iam::${{ secrets.IMPL_ACCOUNT_ID }}:role/delegatedadmin/developer/ab2d-test-github-actions + role-to-assume: arn:aws:iam::${{ secrets[format('{0}_ACCOUNT_ID', inputs.environment)] }}:role/delegatedadmin/developer/ab2d-${{ inputs.environment }}-github-actions - - name: Set env vars from AWS params in impl account + - name: Set env vars from AWS params in AB2D account uses: cmsgov/ab2d-bcda-dpc-platform/actions/aws-params-env-action@main env: AWS_REGION: ${{ vars.AWS_REGION }} @@ -70,7 +82,8 @@ jobs: - name: Create opt/ab2d directory and download keystore run: | mkdir -p opt/ab2d - aws s3 cp s3://ab2d-east-impl-main/ab2d_imp_keystore $AB2D_BFD_KEYSTORE_LOCATION + KEYSTORE_FILE_NAME="ab2d_${{ inputs.environment == 'test' && 'imp' || inputs.environment }}_keystore" + aws s3 cp s3://ab2d-${{ vars[format('{0}_DEPLOYMENT_ENV', inputs.environment)] }}-main/$KEYSTORE_FILE_NAME $AB2D_BFD_KEYSTORE_LOCATION test -f $AB2D_BFD_KEYSTORE_LOCATION && echo "created keystore file" - name: Run e2e-bfd-test @@ -79,6 +92,6 @@ jobs: - name: Run e2e-test env: - E2E_ENVIRONMENT: 'IMPL' + E2E_ENVIRONMENT: ${{ inputs.environment == 'dev' && 'DEV' || inputs.environment == 'test' && 'IMPL' || inputs.environment == 'sbx' && 'SANDBOX' }} run: | mvn test -s settings.xml -pl e2e-test -am -Dtest=TestRunner -DfailIfNoTests=false -Dusername=$ARTIFACTORY_USER -Dpassword=$ARTIFACTORY_PASSWORD -Drepository_url=$ARTIFACTORY_URL --no-transfer-progress diff --git a/.github/workflows/promote.yml b/.github/workflows/promote.yml new file mode 100644 index 000000000..f167abfff --- /dev/null +++ b/.github/workflows/promote.yml @@ -0,0 +1,60 @@ +name: promote + +on: + workflow_call: + inputs: + environment: + required: true + type: string + module: + required: true + type: string + workflow_dispatch: + inputs: + environment: + required: true + type: choice + options: + - sbx + - prod + - prod_test + module: + required: true + type: choice + options: + - api + - worker + +permissions: + contents: read + id-token: write + +jobs: + promote: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 + with: + aws-region: ${{ vars.AWS_REGION }} + role-to-assume: arn:aws:iam::${{ secrets.MGMT_ACCOUNT_ID }}:role/delegatedadmin/developer/ab2d-mgmt-github-actions + - name: Retag images in ECR + env: + DEPLOYMENT_ENV: ${{ vars[format('{0}_DEPLOYMENT_ENV', inputs.environment)] }} + ECR_REPO_DOMAIN: ${{ secrets.MGMT_ACCOUNT_ID }}.dkr.ecr.${{ vars.AWS_REGION }}.amazonaws.com + ECR_REPO: ab2d_${{ inputs.module }} + run: | + SHA_SHORT="$(git rev-parse --short HEAD)" + TOKEN="$(aws ecr get-authorization-token --output text --query 'authorizationData[].authorizationToken')" + CONTENT_TYPE="application/vnd.docker.distribution.manifest.v2+json" + + echo "Getting the manifest of the image tagged main-$SHA_SHORT" + MANIFEST="$(curl -sS -H "Authorization: Basic $TOKEN" -H "Accept: $CONTENT_TYPE" "https://$ECR_REPO_DOMAIN/v2/$ECR_REPO/manifests/main-$SHA_SHORT")" + + SHA_TAG="ab2d-$DEPLOYMENT_ENV-$SHA_SHORT" + echo "Adding the $SHA_TAG tag to main-$SHA_SHORT image" + curl -sS -X PUT -H "Authorization: Basic $TOKEN" -H "Content-Type: $CONTENT_TYPE" -d "$MANIFEST" "https://$ECR_REPO_DOMAIN/v2/$ECR_REPO/manifests/$SHA_TAG" + + LATEST_TAG="ab2d-$DEPLOYMENT_ENV-latest" + echo "Adding the $LATEST_TAG tag to main-$SHA_SHORT image" + curl -sS -X PUT -H "Authorization: Basic $TOKEN" -H "Content-Type: $CONTENT_TYPE" -d "$MANIFEST" "https://$ECR_REPO_DOMAIN/v2/$ECR_REPO/manifests/$LATEST_TAG" diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 000000000..0ffffceb5 --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,47 @@ +name: pull request jobs + +on: + pull_request: + +jobs: + unit-integration-test: + uses: ./.github/workflows/unit-integration-test.yml + secrets: inherit + build-api: + uses: ./.github/workflows/build.yml + with: + environment: test + module: api + secrets: inherit + build-worker: + uses: ./.github/workflows/build.yml + with: + environment: test + module: worker + secrets: inherit + deploy-api: + needs: build-api + permissions: + contents: read + id-token: write + uses: ./.github/workflows/deploy.yml + with: + environment: test + module: api + secrets: inherit + deploy-worker: + needs: build-worker + permissions: + contents: read + id-token: write + uses: ./.github/workflows/deploy.yml + with: + environment: test + module: worker + secrets: inherit + e2e-test: + needs: [deploy-api, deploy-worker] + uses: ./.github/workflows/e2e-test.yml + with: + environment: test + secrets: inherit diff --git a/.github/workflows/push-main.yml b/.github/workflows/push-main.yml new file mode 100644 index 000000000..3e5ac51fa --- /dev/null +++ b/.github/workflows/push-main.yml @@ -0,0 +1,46 @@ +name: push to main + +on: + push: + branches: + - main + +jobs: + build-api: + uses: ./.github/workflows/build.yml + with: + environment: test + module: api + secrets: inherit + build-worker: + uses: ./.github/workflows/build.yml + with: + environment: test + module: worker + secrets: inherit + deploy-api: + needs: build-api + permissions: + contents: read + id-token: write + uses: ./.github/workflows/deploy.yml + with: + environment: test + module: api + secrets: inherit + deploy-worker: + needs: build-worker + permissions: + contents: read + id-token: write + uses: ./.github/workflows/deploy.yml + with: + environment: test + module: worker + secrets: inherit + e2e-test: + needs: [deploy-api, deploy-worker] + uses: ./.github/workflows/e2e-test.yml + with: + environment: test + secrets: inherit diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..aa25edd3d --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,89 @@ +name: release + +on: + release: + types: [released] + workflow_dispatch: + +permissions: + contents: read + id-token: write + +jobs: + # Promote and Deploy to prod-test, which only includes worker + promote-prod-test-worker: + uses: ./.github/workflows/promote.yml + with: + environment: prod_test + module: worker + secrets: inherit + + deploy-prod-test-worker: + needs: promote-prod-test-worker + uses: ./.github/workflows/deploy.yml + with: + environment: prod_test + module: worker + secrets: inherit + + # Promote and Deploy to prod + promote-prod-api: + uses: ./.github/workflows/promote.yml + with: + environment: prod + module: api + secrets: inherit + + promote-prod-worker: + uses: ./.github/workflows/promote.yml + with: + environment: prod + module: worker + secrets: inherit + + deploy-prod-api: + needs: promote-prod-api + uses: ./.github/workflows/deploy.yml + with: + environment: prod + module: api + secrets: inherit + + deploy-prod-worker: + needs: promote-prod-worker + uses: ./.github/workflows/deploy.yml + with: + environment: prod + module: worker + secrets: inherit + + # Promote and Deploy to sandbox + promote-sbx-api: + uses: ./.github/workflows/promote.yml + with: + environment: sbx + module: api + secrets: inherit + + promote-sbx-worker: + uses: ./.github/workflows/promote.yml + with: + environment: sbx + module: worker + secrets: inherit + + deploy-sbx-api: + needs: promote-sbx-api + uses: ./.github/workflows/deploy.yml + with: + environment: sbx + module: api + secrets: inherit + + deploy-sbx-worker: + needs: promote-sbx-worker + uses: ./.github/workflows/deploy.yml + with: + environment: sbx + module: worker + secrets: inherit diff --git a/.github/workflows/unit-integration-test.yml b/.github/workflows/unit-integration-test.yml index bc6faeeb0..f4fcdafc2 100644 --- a/.github/workflows/unit-integration-test.yml +++ b/.github/workflows/unit-integration-test.yml @@ -1,7 +1,7 @@ name: Run unit and integration tests on: - pull_request: + workflow_call: workflow_dispatch: # Allow manual trigger jobs: @@ -14,6 +14,8 @@ jobs: steps: - name: Checkout Code uses: actions/checkout@v3 + with: + fetch-depth: 0 # Get entire history for SonarQube - name: Setup Java uses: actions/setup-java@v3 @@ -54,10 +56,10 @@ jobs: run: | mvn -ntp -U clean - - name: SonarQube analysis + - name: Run unit and integration tests run: | - mvn -ntp -s settings.xml ${RUNNER_DEBUG:+"--debug"} compile sonar:sonar -Dsonar.projectKey=ab2d-project -Dsonar.qualitygate.wait=true -DskipTests -Dusername=${ARTIFACTORY_USER} -Dpassword=${ARTIFACTORY_PASSWORD} -Drepository_url=${ARTIFACTORY_URL} + mvn -ntp -s settings.xml ${RUNNER_DEBUG:+"--debug"} -Dusername=${ARTIFACTORY_USER} -Dpassword=${ARTIFACTORY_PASSWORD} -Drepository_url=${ARTIFACTORY_URL} test -pl common,job,coverage,api,worker - - name: Run unit and integration tests + - name: SonarQube analysis run: | - mvn -ntp -s settings.xml ${RUNNER_DEBUG:+"--debug"} -Dusername=${ARTIFACTORY_USER} -Dpassword=${ARTIFACTORY_PASSWORD} -Drepository_url=${ARTIFACTORY_URL} test -pl common,job,coverage,api,worker + mvn -ntp -s settings.xml ${RUNNER_DEBUG:+"--debug"} package sonar:sonar -Dsonar.projectKey=ab2d-project -Dsonar.qualitygate.wait=true -DskipTests -Dusername=${ARTIFACTORY_USER} -Dpassword=${ARTIFACTORY_PASSWORD} -Drepository_url=${ARTIFACTORY_URL} diff --git a/.gitleaks.toml b/.gitleaks.toml new file mode 100644 index 000000000..5cbcbcf64 --- /dev/null +++ b/.gitleaks.toml @@ -0,0 +1,9 @@ +title = "DASG Standard" + +[extend] + useDefault = true + +[[rules]] + id = "mbi-detection" + description = "Detects a potential MBI pattern based on https://www.cms.gov/medicare/new-medicare-card/understanding-the-mbi.pdf" + regex = '''\b((?i)[1-9][ACDEFGHJKMNPQRTUVWXY][ACDEFGHJKMNPQRTUVWXY\d]-?\d[ACDEFGHJKMNPQRTUVWXY][ACDEFGHJKMNPQRTUVWXY\d]\d-?[ACDEFGHJKMNPQRTUVWXY]{2}\d{2})\b''' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c9528f476..f07a239a3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,5 @@ repos: - repo: https://github.com/gitleaks/gitleaks - rev: v8.16.1 + rev: v8.19.2 hooks: - id: gitleaks diff --git a/api/src/main/java/gov/cms/ab2d/api/config/OpenAPIConfig.java b/api/src/main/java/gov/cms/ab2d/api/config/OpenAPIConfig.java index 4fd5f29f3..a9f090872 100644 --- a/api/src/main/java/gov/cms/ab2d/api/config/OpenAPIConfig.java +++ b/api/src/main/java/gov/cms/ab2d/api/config/OpenAPIConfig.java @@ -142,7 +142,7 @@ public OpenApiCustomiser defaultResponseMessages() { @JsonPropertyOrder({ "text" }) - static class Details { + public static class Details { @JsonProperty("text") private String text; @@ -177,7 +177,7 @@ public void setAdditionalProperty(String name, Object value) { "code", "details" }) - static class Issue { + public static class Issue { @JsonProperty("severity") private String severity; @JsonProperty("code") diff --git a/api/src/main/java/gov/cms/ab2d/api/controller/common/StatusCommon.java b/api/src/main/java/gov/cms/ab2d/api/controller/common/StatusCommon.java index 14cc812d4..15dc72759 100644 --- a/api/src/main/java/gov/cms/ab2d/api/controller/common/StatusCommon.java +++ b/api/src/main/java/gov/cms/ab2d/api/controller/common/StatusCommon.java @@ -1,5 +1,6 @@ package gov.cms.ab2d.api.controller.common; +import gov.cms.ab2d.api.config.OpenAPIConfig; import gov.cms.ab2d.api.controller.JobCompletedResponse; import gov.cms.ab2d.api.controller.JobProcessingException; import gov.cms.ab2d.api.controller.TooManyRequestsException; @@ -11,6 +12,7 @@ import gov.cms.ab2d.eventclient.events.ApiResponseEvent; import gov.cms.ab2d.job.dto.JobPollResult; import gov.cms.ab2d.job.model.JobOutput; + import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; @@ -25,7 +27,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; - import static gov.cms.ab2d.api.controller.common.ApiText.X_PROG; import static gov.cms.ab2d.common.util.Constants.FHIR_PREFIX; import static gov.cms.ab2d.common.util.Constants.JOB_LOG; @@ -33,6 +34,7 @@ import static gov.cms.ab2d.common.util.Constants.REQUEST_ID; import static org.springframework.http.HttpHeaders.EXPIRES; import static org.springframework.http.HttpHeaders.RETRY_AFTER; +import static org.springframework.http.MediaType.APPLICATION_JSON; @Service @Slf4j @@ -41,6 +43,7 @@ public class StatusCommon { private final JobClient jobClient; private final SQSEventClient eventLogger; private final int retryAfterDelay; + private final OpenAPIConfig openApi; StatusCommon(PdpClientService pdpClientService, JobClient jobClient, SQSEventClient eventLogger, @Value("${api.retry-after.delay}") int retryAfterDelay) { @@ -48,6 +51,8 @@ public class StatusCommon { this.jobClient = jobClient; this.eventLogger = eventLogger; this.retryAfterDelay = retryAfterDelay; + + this.openApi = new OpenAPIConfig(); } public void throwFailedResponse(String msg) { @@ -80,6 +85,8 @@ public ResponseEntity doStatus(String jobUuid, HttpServletRequest request, Strin "Job in progress", jobPollResult.getProgress() + "% complete", (String) request.getAttribute(REQUEST_ID))); return new ResponseEntity<>(null, responseHeaders, HttpStatus.ACCEPTED); + case CANCELLED: + return getCanceledResponse(jobPollResult, jobUuid, request); case FAILED: throwFailedResponse("Job failed while processing"); break; @@ -117,6 +124,31 @@ protected JobCompletedResponse getJobCompletedResponse(JobPollResult jobPollResu return resp; } + protected ResponseEntity getCanceledResponse(JobPollResult jobPollResult, String jobUuid, HttpServletRequest request) { + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.setContentType(APPLICATION_JSON); + + OpenAPIConfig.OperationOutcome outcome = openApi.new OperationOutcome(); + outcome.setResourceType("OperationOutcome"); + + OpenAPIConfig.Details details = new OpenAPIConfig.Details(); + details.setText("Job is canceled."); + + OpenAPIConfig.Issue issue = new OpenAPIConfig.Issue(); + issue.setDetails(details); + issue.setCode("deleted"); + issue.setSeverity("error"); + + List issuesList = new ArrayList<>(); + issuesList.add(issue); + outcome.setIssue(issuesList); + + eventLogger.sendLogs(new ApiResponseEvent(MDC.get(ORGANIZATION), jobUuid, HttpStatus.NOT_FOUND, + "Job was previously canceled", null, (String) request.getAttribute(REQUEST_ID))); + + return new ResponseEntity(outcome, responseHeaders, HttpStatus.NOT_FOUND); + } + private String getUrlPath(String jobUuid, String filePath, HttpServletRequest request, String apiPrefix) { return Common.getUrl(apiPrefix + FHIR_PREFIX + "/Job/" + jobUuid + "/file/" + filePath, request); } diff --git a/api/src/main/java/gov/cms/ab2d/api/security/JwtTokenAuthenticationFilter.java b/api/src/main/java/gov/cms/ab2d/api/security/JwtTokenAuthenticationFilter.java index ee12280ef..1ba032d00 100644 --- a/api/src/main/java/gov/cms/ab2d/api/security/JwtTokenAuthenticationFilter.java +++ b/api/src/main/java/gov/cms/ab2d/api/security/JwtTokenAuthenticationFilter.java @@ -223,6 +223,11 @@ private boolean shouldBePublic(String requestUri) { return true; } + if (requestUri.endsWith("/metadata")) { + log.debug("metadata requested"); + return true; + } + return false; } diff --git a/api/src/main/java/gov/cms/ab2d/api/security/SecurityConfig.java b/api/src/main/java/gov/cms/ab2d/api/security/SecurityConfig.java index 98dc8efa9..c29d530f4 100644 --- a/api/src/main/java/gov/cms/ab2d/api/security/SecurityConfig.java +++ b/api/src/main/java/gov/cms/ab2d/api/security/SecurityConfig.java @@ -48,7 +48,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { private final String[] authExceptions = new String[]{"/swagger-ui/**", "/configuration/**", "/swagger-resources/**", "/v3/api-docs/**", "/webjars/**", AKAMAI_TEST_OBJECT, "/favicon.ico", "/error", HEALTH_ENDPOINT, STATUS_ENDPOINT, - "/metadata"}; + "/**/metadata"}; @Override protected void configure(HttpSecurity security) throws Exception { @@ -62,9 +62,9 @@ protected void configure(HttpSecurity security) throws Exception { // Add a filter to validate the tokens with every request. .addFilterAfter(jwtTokenAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) .authorizeHttpRequests() + .antMatchers(authExceptions).permitAll() .antMatchers(API_PREFIX_V1 + ADMIN_PREFIX + "/**").hasAuthority(ADMIN_ROLE) .antMatchers(API_PREFIX_V1 + FHIR_PREFIX + "/**").hasAnyAuthority(SPONSOR_ROLE) - .antMatchers(authExceptions).permitAll() .anyRequest().authenticated(); // Override default behavior to add more informative logs diff --git a/api/src/test/java/gov/cms/ab2d/api/controller/common/StatusCommonTest.java b/api/src/test/java/gov/cms/ab2d/api/controller/common/StatusCommonTest.java index 88b9e060f..7c9e7be59 100644 --- a/api/src/test/java/gov/cms/ab2d/api/controller/common/StatusCommonTest.java +++ b/api/src/test/java/gov/cms/ab2d/api/controller/common/StatusCommonTest.java @@ -67,7 +67,7 @@ void testTooFrequentInvocations() { } @Test - void testDoStatus1() { + void testDoStatusSuccessful() { when(jobPollResult.getStatus()).thenReturn(JobStatus.SUCCESSFUL); assertNotNull( statusCommon.doStatus("1234", req, "prefix") @@ -75,7 +75,7 @@ void testDoStatus1() { } @Test - void testDoStatus2() { + void testDoStatusSubmitted() { when(jobPollResult.getStatus()).thenReturn(JobStatus.SUBMITTED); assertNotNull( statusCommon.doStatus("1234", req, "prefix") @@ -83,7 +83,7 @@ void testDoStatus2() { } @Test - void testDoStatus3() { + void testDoStatusInProgress() { when(jobPollResult.getStatus()).thenReturn(JobStatus.IN_PROGRESS); assertNotNull( statusCommon.doStatus("1234", req, "prefix") @@ -91,7 +91,7 @@ void testDoStatus3() { } @Test - void testDoStatus4() { + void testDoStatusFailed() { when(jobPollResult.getStatus()).thenReturn(JobStatus.FAILED); assertThrows(JobProcessingException.class, () -> { statusCommon.doStatus("1234", req, "prefix"); @@ -99,11 +99,11 @@ void testDoStatus4() { } @Test - void testDoStatus5() { + void testDoStatusCanceled() { when(jobPollResult.getStatus()).thenReturn(JobStatus.CANCELLED); - assertThrows(JobProcessingException.class, () -> { - statusCommon.doStatus("1234", req, "prefix"); - }); + assertNotNull( + statusCommon.doStatus("1234", req, "prefix") + ); } @Test @@ -120,4 +120,11 @@ void testGetJobCompletedResponse() { ); } + @Test + void testGetJobCanceledResponse() { + assertNotNull( + statusCommon.getCanceledResponse(jobPollResult, "1234", req) + ); + } + }