Skip to content

Commit

Permalink
Merge pull request #47 from opensrp/sync-with-upstream-0.3.0
Browse files Browse the repository at this point in the history
Sync with upstream 0.3.0
  • Loading branch information
ndegwamartin authored Oct 5, 2023
2 parents 00a4bea + 6f990af commit 38db089
Show file tree
Hide file tree
Showing 56 changed files with 1,009 additions and 2,938 deletions.
77 changes: 77 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"

on:
push:
branches: [ "main" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "main" ]
schedule:
- cron: '25 21 * * 6'

jobs:
analyze:
name: Analyze
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
permissions:
actions: read
contents: read
security-events: write

strategy:
fail-fast: false
matrix:
language: [ 'java', 'python' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift' ]
# Use only 'java' to analyze code written in Java, Kotlin or both
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support

steps:
- name: Checkout repository
uses: actions/checkout@v3

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.

# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality


# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2

# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun

# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.

# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

# Image for building and running tests against the source code of
# the FHIR Gateway.
FROM maven:3.8.5-openjdk-17-slim as build
FROM maven:3.8.5-openjdk-11-slim as build

RUN apt-get update && apt-get install -y nodejs npm
RUN npm cache clean -f && npm install -g n && n stable
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ all pieces can be woven together into a single Spring Boot app. To build all
modules, from the root run:

```shell
mvn package
mvn package -Dspotless.apply.skip=true
```

The server and the plugins can be run together through this executable jar (
Expand Down
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash
#
# Copyright 2021-2022 Google LLC
# Copyright 2021-2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion charts/fhir-gateway/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright 2021-2022 Google LLC
# Copyright 2021-2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion charts/fhir-gateway/templates/configmap.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright 2021-2022 Google LLC
# Copyright 2021-2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion charts/fhir-gateway/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright 2021-2022 Google LLC
# Copyright 2021-2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion charts/fhir-gateway/templates/hpa.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright 2021-2022 Google LLC
# Copyright 2021-2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion charts/fhir-gateway/templates/ingress.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright 2021-2022 Google LLC
# Copyright 2021-2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion charts/fhir-gateway/templates/pdb.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright 2021-2022 Google LLC
# Copyright 2021-2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion charts/fhir-gateway/templates/service.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright 2021-2022 Google LLC
# Copyright 2021-2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion charts/fhir-gateway/templates/serviceaccount.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright 2021-2022 Google LLC
# Copyright 2021-2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion charts/fhir-gateway/templates/tests/test-connection.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright 2021-2022 Google LLC
# Copyright 2021-2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion charts/fhir-gateway/templates/vpa.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright 2021-2022 Google LLC
# Copyright 2021-2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion charts/fhir-gateway/values.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright 2021-2022 Google LLC
# Copyright 2021-2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion docker/hapi-proxy-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright 2021-2022 Google LLC
# Copyright 2021-2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
4 changes: 2 additions & 2 deletions e2e-test/clients.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright 2021-2022 Google LLC
# Copyright 2021-2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -65,7 +65,7 @@ class FhirProxyClient:
"""

def __init__(self, host: str = "http://localhost", port: int = 8080) -> None:
self.base_url = "{}:{}".format(host, port)
self.base_url = "{}:{}/fhir".format(host, port)
self.session = _setup_session(self.base_url)

def get_resource_count(
Expand Down
2 changes: 1 addition & 1 deletion e2e-test/e2e.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash
#
# Copyright 2021-2022 Google LLC
# Copyright 2021-2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
12 changes: 12 additions & 0 deletions exec/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Sample application

This module is to show simple examples of how to use the FHIR Gateway. The
minimal application is
[MainApp](src/main/java/com/google/fhir/gateway/MainApp.java). With this single
class, you can create an executable app with the Gateway [server](../server) and
all of the `AccessChecker` [plugins](../plugins), namely
[ListAccessChecker](../plugins/src/main/java/com/google/fhir/gateway/plugin/ListAccessChecker.java)
and
[PatientAccessChecker](../plugins/src/main/java/com/google/fhir/gateway/plugin/PatientAccessChecker.java).

Two other classes are provided to show how to implement custom endpoints.
2 changes: 1 addition & 1 deletion exec/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<parent>
<groupId>com.google.fhir.gateway</groupId>
<artifactId>fhir-gateway</artifactId>
<version>0.1.32</version>
<version>0.3.0</version>
</parent>

<artifactId>exec</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright 2021-2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.fhir.gateway;

import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.parser.IParser;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.ListResource;
import org.hl7.fhir.r4.model.ListResource.ListEntryComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* This is an example servlet that requires a valid JWT to be present as the Bearer Authorization
* header. Although it is not a standard FHIR query, but it uses the FHIR server to construct the
* response. In this example, it inspects the JWT and depending on its claims, constructs the list
* of Patient IDs that the user has access to.
*
* <p>The two types of tokens resemble {@link com.google.fhir.gateway.plugin.ListAccessChecker} and
* {@link com.google.fhir.gateway.plugin.PatientAccessChecker} expected tokens. But those are just
* picked as examples and this custom endpoint is independent of any {@link
* com.google.fhir.gateway.interfaces.AccessChecker}.
*/
@WebServlet("/myPatients")
public class CustomFhirEndpointExample extends HttpServlet {

private static final Logger logger = LoggerFactory.getLogger(CustomFhirEndpointExample.class);
private final TokenVerifier tokenVerifier;

private final HttpFhirClient fhirClient;

public CustomFhirEndpointExample() throws IOException {
this.tokenVerifier = TokenVerifier.createFromEnvVars();
this.fhirClient = FhirClientFactory.createFhirClientFromEnvVars();
}

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Check the Bearer token to be a valid JWT with required claims.
String authHeader = request.getHeader("Authorization");
if (authHeader == null) {
throw new ServletException("No Authorization header provided!");
}
List<String> patientIds = new ArrayList<>();
// Note for a more meaningful HTTP status code, we can catch AuthenticationException in:
DecodedJWT jwt = tokenVerifier.decodeAndVerifyBearerToken(authHeader);
Claim claim = jwt.getClaim("patient_list");
if (claim.asString() != null) {
logger.info("Found a 'patient_list' claim: {}", claim);
String listUri = "List/" + claim.asString();
HttpResponse fhirResponse = fhirClient.getResource(listUri);
HttpUtil.validateResponseOrFail(fhirResponse, listUri);
if (fhirResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
logger.error("Error while fetching {}", listUri);
response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
return;
}
FhirContext fhirContext = FhirContext.forCached(FhirVersionEnum.R4);
IParser jsonParser = fhirContext.newJsonParser();
IBaseResource resource = jsonParser.parseResource(fhirResponse.getEntity().getContent());
ListResource listResource = (ListResource) resource;
for (ListEntryComponent entry : listResource.getEntry()) {
patientIds.add(entry.getItem().getReference());
}
} else {
claim = jwt.getClaim("patient_id");
if (claim.asString() != null) {
logger.info("Found a 'patient_id' claim: {}", claim);
patientIds.add(claim.asString());
}
}
if (claim.asString() == null) {
String error = "Found no patient claim in the token!";
logger.error(error);
response.getOutputStream().print(error);
response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
return;
}
response.getOutputStream().print("Your patient are: " + String.join(" ", patientIds));
response.setStatus(HttpStatus.SC_OK);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2021-2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.fhir.gateway;

import java.io.IOException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.http.HttpStatus;

/**
* This is an example servlet that can be used for any custom endpoint. It does not make any
* assumptions about authorization headers or accessing a FHIR server.
*/
@WebServlet("/custom/*")
public class CustomGenericEndpointExample extends HttpServlet {

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws IOException {
String uri = request.getRequestURI();
// For a real production case, `uri` needs to be escaped.
resp.getOutputStream().print("Successful request to the custom endpoint " + uri);
resp.setStatus(HttpStatus.SC_OK);
}
}
4 changes: 4 additions & 0 deletions exec/src/main/java/com/google/fhir/gateway/MainApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

/**
* This class shows the minimum that is required to create a FHIR Gateway with all AccessChecker
* plugins defined in "com.google.fhir.gateway.plugin".
*/
@SpringBootApplication(scanBasePackages = {"com.google.fhir.gateway.plugin"})
@ServletComponentScan(basePackages = "com.google.fhir.gateway")
public class MainApp {
Expand Down
Loading

0 comments on commit 38db089

Please sign in to comment.