-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add initial package and configuration files for FHIR info Gateway #304
base: main
Are you sure you want to change the base?
Add initial package and configuration files for FHIR info Gateway #304
Conversation
WalkthroughThis pull request introduces the FHIR Info Gateway, an infrastructure package that serves as an intermediary between OpenHIM, MPI Mediator, and FHIR access. The changes encompass Docker configurations, package metadata definitions, Keycloak authentication setup, deployment scripts, and extensive documentation. The implementation aims to create a secure and configurable gateway for managing FHIR-based requests with effective authentication and routing capabilities. Changes
Sequence DiagramsequenceDiagram
participant Client
participant Keycloak
participant OpenHIM
participant "FHIR Info Gateway"
participant "MPI Mediator"
Client->>Keycloak: Request Authentication
Keycloak-->>Client: Provide Token
Client->>OpenHIM: FHIR Request with Token
OpenHIM->>FHIR Info Gateway: Route Request
FHIR Info Gateway->>Keycloak: Validate Token
Keycloak-->>FHIR Info Gateway: Token Validation
FHIR Info Gateway->>MPI Mediator: Forward Request
MPI Mediator-->>FHIR Info Gateway: Response
FHIR Info Gateway-->>OpenHIM: Return Response
OpenHIM-->>Client: Deliver Response
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI ⛔ Files ignored due to path filters (6)
📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
a63ddec
to
8e2c200
Compare
a821ec4
to
541a022
Compare
541a022
to
b0a333c
Compare
THe mpi mediator has been modified and the returned response has a different structure
This also adds bootstrapper node placement. Has to be on the leader where the commands are run as we run a command in the bootstrapper docker container
aa68f9c
to
2b94455
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (3)
- fhir-info-gateway/docker-compose-smart_keycloak.yml (1 hunks)
- fhir-info-gateway/keycloak-config.json (1 hunks)
- fhir-info-gateway/package-metadata.json (1 hunks)
Files skipped from review as they are similar to previous changes (2)
- fhir-info-gateway/keycloak-config.json
- fhir-info-gateway/package-metadata.json
Additional comments not posted (5)
fhir-info-gateway/docker-compose-smart_keycloak.yml (5)
1-1
: Specify a more recent Docker Compose version if needed.The file uses version "3.9". Ensure this version is appropriate for your use case and consider using a more recent version if new features are needed.
4-5
: Ensure the image version is appropriate.The
smart-config
service uses thejembi/keycloak-config:v0.0.1
image. Verify that this version is stable and meets your requirements.
8-12
: Verify environment variable values.Ensure that the environment variables
KEYCLOAK_BASE_URL
,KEYCLOAK_USER
,KEYCLOAK_PASSWORD
, andKEYCLOAK_REALM
are correctly set in your environment to avoid runtime errors.
13-13
: Check the configuration file path.The command specifies a configuration file path
config/backend-services-config.json
. Ensure this path is correct and the file exists in the expected location.
14-17
: Ensure external network availability.The
keycloak
network is defined as external with the namekeycloak_public
. Verify that this network is available and correctly configured in your Docker environment.
@rcrichton I have updated the image with sample v2 client scopes. You should be able to test now. |
I think we also need to provide some default users, groups and roles in keycloak so it's easier to get this working. We could have a read only role, etc with some default users assigned to those. Also, we expect these 'users' to actually be entire EMR system so i think they need to be created as clients in KC with service accounts enabled. See my arch notes on the clickup task for how to do this. I think we should have all this preconfigured to make it easier on the end user. |
…ration-files-for-FHIR-info-Gateway
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Outside diff range and nitpick comments (2)
fhir-info-gateway/importer/keycloak-config.json (1)
217-225
: Consider using a generic or placeholder email address for the default user.The default user configuration looks good overall. However, the email address "fhir@jembi.org" might not be a valid or appropriate email for a default user. Consider using a more generic or placeholder email address to avoid potential confusion or misuse.
Apply this diff to update the email address:
- "email": "fhir@jembi.org", + "email": "fhir-user@example.com",fhir-info-gateway/importer/update-keycloak-config.js (1)
71-119
: LGTM with a suggestion!The
getOrCreateClient
function is implemented correctly and follows best practices:
- It uses the
axios
library to make the HTTP requests.- The function constructs the clients endpoint URL and sets the necessary headers, including the admin token for authentication.
- It checks if the client exists by searching for it in the response data of the GET request.
- If the client exists, it updates the client using a PUT request with the provided client configuration.
- If the client doesn't exist, it creates a new client using a POST request with the provided client configuration.
- The function logs the result of the operation (updated or created client).
- Error handling is implemented to catch and log any errors that occur during the requests.
Suggestion:
Consider uncommenting thethrow error;
statement on line 117 to propagate the error and handle it at a higher level instead of silently suppressing it.Uncomment the following line to throw the error:
- //throw error; + throw error;
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (2)
- fhir-info-gateway/importer/keycloak-config.json (1 hunks)
- fhir-info-gateway/importer/update-keycloak-config.js (1 hunks)
Additional comments not posted (8)
fhir-info-gateway/importer/keycloak-config.json (3)
2-192
: LGTM!The
clientScopes
configuration is well-structured and covers the necessary FHIR resources. The roles and access levels are appropriately mapped to each scope, and the audience mapper is correctly configured.
195-212
: LGTM!The
client
configuration for the EMR user is correctly set up as a confidential client with service accounts enabled. The necessary OAuth2 and OpenID Connect settings are appropriately configured.
213-215
: Clarify the purpose and usage of thefhirUser
group.The
fhirUser
group is defined but empty. Please provide more information on how this group is intended to be used or populated. Consider adding a description or mapping the group to specific roles or scopes if applicable.fhir-info-gateway/importer/update-keycloak-config.js (5)
15-46
: LGTM!The
getAdminToken
function is implemented correctly and follows best practices:
- It uses the
axios
library to make the HTTP request.- The function constructs the token endpoint URL and sets the necessary headers and request body parameters.
- It extracts the access token from the response data and returns it.
- Error handling is implemented to catch and log any errors that occur during the request.
48-69
: LGTM!The
getRoleByName
function is implemented correctly and follows best practices:
- It uses the
axios
library to make the HTTP request.- The function constructs the roles endpoint URL and sets the necessary headers, including the admin token for authentication.
- It searches for the role by name in the response data and returns the role ID if found, otherwise it returns null.
- Error handling is implemented to catch and log any errors that occur during the request.
121-404
: LGTM!The
processKeycloakPayload
function is implemented correctly and follows best practices:
- It destructures the necessary properties from the payload.
- The function validates the presence of the
clientScopes
property in the payload.- It iterates over each client scope in the payload and performs the necessary operations:
- Creates or updates the role associated with the client scope.
- Creates or updates the client scope itself.
- Maps the created role to the client scope.
- The function creates or updates the service-account user and adds it to the specified group.
- It retrieves the unique roles from the payload using the
getUniqueRolesArray
function and maps them to the group.- The function logs the result of each operation for informational purposes.
- Error handling is implemented to catch and log any errors, and the errors are thrown for further handling.
406-419
: LGTM!The
getUniqueRolesArray
function is implemented correctly and follows best practices:
- It creates a new Set to store the unique roles, ensuring that duplicate roles are eliminated.
- The function extracts the
clientScopes
property from the payload.- It iterates over each client scope in the
clientScopes
object and adds the stringified role to the Set if it exists.- After iterating over all client scopes, the function converts the Set to an array using
Array.from()
.- It then maps over each stringified role in the array and parses it back to an object using
JSON.parse()
.- The function returns the resulting array of unique roles.
422-474
: LGTM!The
main
function is implemented correctly and follows best practices:
- It serves as the entry point of the script and orchestrates the execution flow.
- The function is marked as
async
to allow the use ofawait
for asynchronous operations.- It retrieves the admin token by calling the
getAdminToken
function with the necessary arguments.- The function creates or updates the client by calling the
getOrCreateClient
function with the client configuration and other required arguments.- It retrieves the unique roles from the payload by calling the
getUniqueRolesArray
function.- The function iterates over each unique role and creates or updates it in Keycloak using the
getRoleByName
function andaxios
library.- It processes the Keycloak payload by calling the
processKeycloakPayload
function with the payload and other required arguments.- The function logs a success message if the processing is successful.
- Error handling is implemented using a
try-catch
block to catch and log any errors that occur during the execution.
"resetPassword": { | ||
"temporary": false, | ||
"type": "password", | ||
"value": "dev_password_only" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strongly advise against using the current password in production.
The resetPassword
configuration sets a non-temporary password with the value "dev_password_only". This password is weak and not suitable for production environments. Using such a password poses a significant security risk, as attackers could easily guess or brute-force it, gaining unauthorized access to the system.
Strongly recommend generating a secure, random password for production use. Consider using a password manager or a secure password generation tool to create a strong password with a minimum of 12 characters, including a mix of uppercase and lowercase letters, numbers, and special characters.
Apply this diff to remove the current password:
- "value": "dev_password_only"
+ "value": "<GENERATE_SECURE_PASSWORD>"
Committable suggestion was skipped due to low confidence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (4)
- fhir-info-gateway/importer/docker-compose-smart_keycloak.yml (1 hunks)
- fhir-info-gateway/importer/docker-compose.config.yml (1 hunks)
- fhir-info-gateway/importer/update-keycloak-config.js (1 hunks)
- fhir-info-gateway/swarm.sh (1 hunks)
Additional context used
Biome
fhir-info-gateway/importer/update-keycloak-config.js
[error] 103-103: Can't assign clientResponse because it's a constant
This is where the variable is defined as constant
Unsafe fix: Replace const with let if you assign it to a new value.
(lint/correctness/noConstAssign)
Additional comments not posted (17)
fhir-info-gateway/importer/docker-compose-smart_keycloak.yml (3)
1-13
: LGTM!The Docker Compose version is set correctly, and the
smart-config
service is properly defined with the necessary configuration.
15-18
: LGTM!The
keycloak
network is properly defined as an external network, which is appropriate for a shared network in a microservices architecture.
1-18
: Great work!The Docker Compose file is well-structured, follows best practices, and includes all necessary configurations for deploying the Keycloak service. The use of environment variables for configuration is a good practice for containerized applications.
fhir-info-gateway/importer/docker-compose.config.yml (4)
3-10
: LGTM!The
update-keycloak-config
service definition looks good:
- The choice of the Node.js image version is appropriate for the task.
- The environment variables are sourced from the Docker environment, which is a good practice.
- The command installs the required dependencies and runs the configuration update script.
11-15
: Configuration files are mapped correctly.The configuration files are mapped to the correct locations in the service's container. Please ensure that the contents of
update-keycloak-config.js
andkeycloak-config.json
are correct and align with the Keycloak configuration requirements.
16-19
: Deployment configuration is appropriate.The deployment configuration for the
update-keycloak-config
service is appropriate:
- Having one replica is sufficient for this type of service.
- The restart policy ensures that the service does not automatically restart, which is appropriate for a one-time configuration update task.
20-21
: Network configuration is correct.The
update-keycloak-config
service is correctly connected to thekeycloak_public
network, which allows it to communicate with the Keycloak server. Please ensure that thekeycloak_public
network is properly defined in the relevant Docker Compose file.Also applies to: 33-36
fhir-info-gateway/swarm.sh (4)
1-8
: LGTM!The shebang line and variable declarations look good. The variables are initialized with appropriate default values.
31-35
: LGTM!The
import_sources
function looks good. It imports the necessary utility scripts and uses a shellcheck directive to disable a specific warning.
37-58
: LGTM!The
initialize_package
function looks good. It handles the deployment of the package based on the mode and action. It also deploys a config importer if necessary and removes a specific service after deployment. The error handling and logging are in place.
60-85
: LGTM!The
destroy_package
function and themain
function look good. Thedestroy_package
function destroys the package using the appropriate utility function. Themain
function is well-structured and handles different actions by calling the appropriate functions. The logging messages are informative and cover all the cases. The error handling for invalid actions is in place.fhir-info-gateway/importer/update-keycloak-config.js (6)
19-50
: LGTM!The function correctly retrieves the admin token from Keycloak and handles errors appropriately.
52-73
: LGTM!The function correctly retrieves the role by name from Keycloak and handles errors appropriately.
75-123
: LGTM!The function correctly retrieves or creates the client in Keycloak and handles errors appropriately. Just make sure to address the constant variable assignment issue.
Tools
Biome
[error] 103-103: Can't assign clientResponse because it's a constant
This is where the variable is defined as constant
Unsafe fix: Replace const with let if you assign it to a new value.
(lint/correctness/noConstAssign)
125-410
: LGTM!The function correctly processes the Keycloak payload, handling the creation and mapping of roles, client scopes, and the service account user. The logic appears to be sound, but the function could benefit from some refactoring to improve its structure.
411-424
: LGTM!The function correctly retrieves the unique roles from the payload using a Set to ensure uniqueness. The logic is clear and concise.
426-485
: LGTM!The
main
function correctly orchestrates the Keycloak configuration process by retrieving the admin token, managing the client, processing unique roles, and handling the payload processing. The error handling is appropriate, and the function provides a clear entry point for the script.
console.log(`Updated user: ${defaultUser.username}`); | ||
} else { | ||
// User does not exist, create a new one | ||
userResponse = await axios.post( | ||
`${keycloakBaseUrl}/admin/realms/${realm}/users`, | ||
defaultUser, | ||
{ | ||
headers: { | ||
Authorization: `Bearer ${adminToken}`, | ||
"Content-Type": "application/json", | ||
}, | ||
} | ||
); | ||
console.log(`Created user: ${defaultUser.username}`); | ||
} | ||
|
||
const createdUser = userResponse.data; | ||
console.log("here", user); | ||
// Reset the password | ||
const newPass = await axios.put( | ||
`${keycloakBaseUrl}/admin/realms/${realm}/users/${ | ||
userResponse.id ? userResponse.id : user.id | ||
}/reset-password`, | ||
resetPassword, | ||
{ | ||
headers: { | ||
Authorization: `Bearer ${adminToken}`, | ||
"Content-Type": "application/json", | ||
}, | ||
} | ||
); | ||
console.log(`Reset password for user ${createdUser}`, newPass.data); | ||
// Step 5: Add service-account user to the group | ||
await axios.put( | ||
`${keycloakBaseUrl}/admin/realms/${realm}/users/${ | ||
createdUser.id ? createdUser.id : user.id | ||
}/groups/${groupId}`, | ||
{}, | ||
{ | ||
headers: { | ||
Authorization: `Bearer ${adminToken}`, | ||
"Content-Type": "application/json", | ||
}, | ||
} | ||
); | ||
console.log(`Added ${createdUser} to group ${createdgroupResponse}`); | ||
const uniqueRolesArray = await getUniqueRolesArray(payload); | ||
for (const role of uniqueRolesArray) { | ||
const roleID = await getRoleByName( | ||
role.name, | ||
keycloakBaseUrl, | ||
realm, | ||
adminToken | ||
); | ||
console.log(roleID); | ||
const roleMapping = await axios.post( | ||
`${keycloakBaseUrl}/admin/realms/${realm}/groups/${groupId}/role-mappings/realm`, | ||
[ | ||
{ | ||
id: roleID, | ||
clientRole: false, | ||
composite: false, | ||
containerId: realm, | ||
name: role.name, | ||
description: role.description, | ||
}, | ||
], | ||
{ | ||
headers: { | ||
Authorization: `Bearer ${adminToken}`, | ||
"Content-Type": "application/json", | ||
}, | ||
} | ||
); | ||
console.log(`Added role mapping to group ${roleMapping}`, role); | ||
} | ||
} catch (error) { | ||
console.error( | ||
"Error creating or updating user:", | ||
error.response ? error.response.data : error.message | ||
); | ||
throw error; | ||
} | ||
|
||
// Step 6: Add role mapping to the group | ||
// Extract unique roles | ||
|
||
// const rolesToBeMapped = []; | ||
// uniqueRolesArray.forEach(async (role) => { | ||
// const rolesToBeMappedPayload = await getRoleByName( | ||
// role.name, | ||
// keycloakBaseUrl, | ||
// realm, | ||
// adminToken | ||
// ); | ||
// console.log(rolesToBeMappedPayload); | ||
// rolesToBeMapped.push(rolesToBeMappedPayload); | ||
// }); | ||
// console.log("sdsdsd", rolesToBeMapped); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider refactoring the function to improve readability and maintainability.
The processKeycloakPayload
function is quite large and complex, handling multiple responsibilities such as processing client scopes, managing roles, updating the service account user, and mapping roles to groups.
To improve readability and maintainability, consider breaking down the function into smaller, focused functions that handle specific tasks. This will make the code easier to understand, test, and maintain.
console.log(`Updated client: ${client.clientId}`); | ||
} else { | ||
// Client does not exist, create a new one | ||
clientResponse = await axios.post( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the assignment to a constant variable.
The static analysis tool correctly identified an issue where the clientResponse
variable, declared with const
, is being reassigned a new value.
To fix this, change the variable declaration to let
:
- clientResponse = await axios.post(
+ let clientResponse = await axios.post(
Committable suggestion was skipped due to low confidence.
Tools
Biome
[error] 103-103: Can't assign clientResponse because it's a constant
This is where the variable is defined as constant
Unsafe fix: Replace const with let if you assign it to a new value.
(lint/correctness/noConstAssign)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is defined in L77
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@drizzentic, thank you for pointing that out. I see that clientResponse
is defined at line 77. My previous comment was incorrect, and I apologize for the confusion.
Learnings added
Learnt from: drizzentic
PR: jembi/platform#304
File: fhir-info-gateway/importer/update-keycloak-config.js:103-103
Timestamp: 2024-09-18T06:50:31.835Z
Learning: When reviewing variable assignments, ensure to verify existing declarations to avoid incorrect suggestions about constant reassignments.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
Hi @rcrichton, |
5579cfb
to
cb22626
Compare
cb22626
to
f965914
Compare
…ration-files-for-FHIR-info-Gateway
@drizzentic I'm struggling to figure out how to test this. Please can you add instructions on how to set this up. These details should go in the gitbook docs, under a FHIR Info Gateway package section here. Some things I feel we need to add to that:
Please also see the suggested suggested default scopes to add in the architecture image here https://app.clickup.com/t/86by26xdn I think we should add those ones only. The PR looks good, but we to better explain how to set it up and test the work. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (1)
documentation/packages/fhir-info-gateway/README.md (1)
112-116
: Update API example with realistic FHIR endpoint.The current example is generic. Include a practical example that demonstrates the default client setup:
```bash curl -X GET \ -H "Authorization: Bearer <token>" \ -"http://localhost:5001/fhir/Encounter" +"http://localhost:5001/fhir/Patient/$match" \ +-H "Content-Type: application/json" \ +-d '{ + "resourceType": "Parameters", + "parameter": [ + { + "name": "identifier", + "valueString": "12345" + } + ] +}'</blockquote></details> </blockquote></details> <details> <summary>📜 Review details</summary> **Configuration used: CodeRabbit UI** **Review profile: CHILL** **Plan: Pro** <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between abfd8514dfb01d0728af279562cdeb1a89266105 and 4a1ad7028f8f2528206c04d9c5f6eb073f42b76c. </details> <details> <summary>📒 Files selected for processing (2)</summary> * `documentation/SUMMARY.md` (1 hunks) * `documentation/packages/fhir-info-gateway/README.md` (1 hunks) </details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
```bash | ||
curl -X POST -d 'client_id=emr' -d 'username=fhiruser' \ | ||
-d 'password=dev_password_only' -d 'grant_type=password' \ | ||
"http://localhost:9088/realms/platform-realm/protocol/openid-connect/token" | jq | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Update client credentials example with default client details.
The current example uses generic placeholders. As per PR comments, include the default client and scopes that were added:
-curl -X POST -d 'client_id=emr' -d 'username=fhiruser' \
-d 'password=dev_password_only' -d 'grant_type=password' \
"http://localhost:9088/realms/platform-realm/protocol/openid-connect/token" | jq
+curl -X POST \
+ -d 'grant_type=client_credentials' \
+ -d 'client_id=fhir_client' \
+ -d 'client_secret=<your_client_secret>' \
+ "http://localhost:9088/realms/platform-realm/protocol/openid-connect/token" | jq
+
+# Note: Replace <your_client_secret> with the secret generated for your client
+# Default scopes assigned: fhir:read, fhir:write
1. Navigate to the OpenHIM console. | ||
2. Update the MPI Channel settings: | ||
- **Channel Name**: MPI Orchestrations | ||
- Ensure all Create/Read requests are routed through the FHIR Info Gateway. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add detailed OpenHIM channel configuration steps.
The OpenHIM channel configuration section lacks specific details requested in the PR comments. Please include:
- Step-by-step instructions for enabling FHIR request routing
- Configuration parameters and their values
- Whether this routing should be enabled by default
Remove the placeholder comment and add detailed configuration steps:
- <!-- _Add configuration details here._ -->
+ 3. Configure the following route settings:
+ - Primary Route: http://fhir-info-gateway:3000
+ - Route Type: HTTP
+ - Add additional routes for FHIR resource endpoints
+
+ Note: By default, direct FHIR request routing is disabled. Enable it only for advanced use cases.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
1. Navigate to the OpenHIM console. | |
2. Update the MPI Channel settings: | |
- **Channel Name**: MPI Orchestrations | |
- Ensure all Create/Read requests are routed through the FHIR Info Gateway. | |
1. Navigate to the OpenHIM console. | |
2. Update the MPI Channel settings: | |
- **Channel Name**: MPI Orchestrations | |
- Ensure all Create/Read requests are routed through the FHIR Info Gateway. | |
3. Configure the following route settings: | |
- Primary Route: http://fhir-info-gateway:3000 | |
- Route Type: HTTP | |
- Add additional routes for FHIR resource endpoints | |
Note: By default, direct FHIR request routing is disabled. Enable it only for advanced use cases. |
1. Open Keycloak Admin Console. | ||
2. Navigate to the **Client Scopes** section for the FHIR resource. | ||
3. Update roles and permissions to enforce restricted access. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance client role management section with default roles.
As per PR comments, document the default roles and users configured in Keycloak:
1. Open Keycloak Admin Console.
2. Navigate to the **Client Scopes** section for the FHIR resource.
-3. Update roles and permissions to enforce restricted access.
+3. Default Configuration:
+ - Role: fhir-readonly
+ - Default Client: fhir_client (service account enabled)
+ - Default Scopes: fhir:read, fhir:write
+
+4. Modify roles and permissions:
+ - Navigate to Clients → fhir_client → Service Account Roles
+ - Add/remove roles to modify access levels
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
1. Open Keycloak Admin Console. | |
2. Navigate to the **Client Scopes** section for the FHIR resource. | |
3. Update roles and permissions to enforce restricted access. | |
1. Open Keycloak Admin Console. | |
2. Navigate to the **Client Scopes** section for the FHIR resource. | |
3. Default Configuration: | |
- Role: fhir-readonly | |
- Default Client: fhir_client (service account enabled) | |
- Default Scopes: fhir:read, fhir:write | |
4. Modify roles and permissions: | |
- Navigate to Clients → fhir_client → Service Account Roles | |
- Add/remove roles to modify access levels |
- [FHIR Info Gateway](packages/fhir-info-gateway/README.md) | ||
- [Environment Variables](packages/fhir-info-gateway/environment-variables.md) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Update environment variables documentation and fix paths
-
Create the missing
documentation/packages/fhir-info-gateway/environment-variables.md
file documenting all environment variables:- Default variables from README:
ACCESS_CHECKER
,REALM_URL
,GATEWAY_ENDPOINT
- Additional variables from docker-compose:
TOKEN_ISSUER
,PROXY_TO
,BACKEND_TYPE
,RUN_MODE
- Deployment variables:
FHIR_INFO_GATEWAY_INSTANCES
,FHIR_INFO_GATEWAY_CPU_LIMIT
, etc.
- Default variables from README:
-
Update paths in SUMMARY.md to use correct directory:
- - [FHIR Info Gateway](packages/fhir-info-gateway/README.md)
- - [Environment Variables](packages/fhir-info-gateway/environment-variables.md)
+ - [FHIR Info Gateway](documentation/packages/fhir-info-gateway/README.md)
+ - [Environment Variables](documentation/packages/fhir-info-gateway/environment-variables.md)
🔗 Analysis chain
Add missing environment variables documentation.
The SUMMARY.md references an environment variables document that hasn't been provided:
packages/fhir-info-gateway/environment-variables.md
Please create this document and include all environment variables listed in the README, along with their:
- Default values
- Validation rules
- Required/Optional status
Run this script to check for the missing file:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check if the environment variables documentation exists
if [ ! -f "documentation/packages/fhir-info-gateway/environment-variables.md" ]; then
echo "Missing file: documentation/packages/fhir-info-gateway/environment-variables.md"
exit 1
fi
Length of output: 260
Script:
#!/bin/bash
# Check if README exists and look for environment variables section
if [ -f "packages/fhir-info-gateway/README.md" ]; then
echo "=== README Content ==="
cat "packages/fhir-info-gateway/README.md"
else
echo "README.md not found"
fi
Length of output: 98
Script:
#!/bin/bash
# Check if the package directory exists and list its contents
echo "=== Checking package directory ==="
if [ -d "packages/fhir-info-gateway" ]; then
echo "Directory exists. Contents:"
ls -la packages/fhir-info-gateway/
else
echo "Directory not found at packages/fhir-info-gateway"
fi
# Search for any files related to this package
echo -e "\n=== Searching for related files ==="
fd "fhir-info-gateway" --hidden --no-ignore
Length of output: 419
Script:
#!/bin/bash
# Check both potential locations for documentation
echo "=== Checking root package directory ==="
ls -la fhir-info-gateway/
echo -e "\n=== Checking documentation directory ==="
ls -la documentation/packages/fhir-info-gateway/
echo -e "\n=== Checking README content ==="
if [ -f "fhir-info-gateway/README.md" ]; then
cat "fhir-info-gateway/README.md"
fi
Length of output: 1002
Script:
#!/bin/bash
echo "=== Documentation README Content ==="
cat "documentation/packages/fhir-info-gateway/README.md"
echo -e "\n=== Checking for environment variables in docker files ==="
echo "docker-compose.yml:"
cat "fhir-info-gateway/docker-compose.yml"
echo -e "\ndocker-compose.dev.yml:"
cat "fhir-info-gateway/docker-compose.dev.yml"
Length of output: 5220
…ration-files-for-FHIR-info-Gateway
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
config.yaml (1)
71-72
: Consider package ordering in profiles.The additions to the cdr profile look good. However, consider grouping related packages together (e.g., fhir-ig-importer and fhir-info-gateway) for better maintainability.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
config.yaml
(3 hunks)documentation/SUMMARY.md
(1 hunks)interoperability-layer-openhim/docker-compose.yml
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- documentation/SUMMARY.md
🔇 Additional comments (2)
config.yaml (1)
30-30
: Verify dependencies for fhir-info-gateway package.The package addition looks good. Since fhir-info-gateway depends on mpi-mediator, verify that the dependency is correctly configured in the package metadata.
✅ Verification successful
Dependencies are correctly configured
The fhir-info-gateway package properly declares mpi-mediator as a dependency in its package-metadata.json file. The runtime configuration also confirms this relationship through the GATEWAY_MPI_PROXY_URL environment variable.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Check if mpi-mediator is listed as a dependency in fhir-info-gateway metadata cat fhir-info-gateway/package-metadata.json | jq -r '.dependencies[] | select(.name == "mpi-mediator")'Length of output: 171
Script:
#!/bin/bash # Check the content of package-metadata.json echo "=== package-metadata.json content ===" cat fhir-info-gateway/package-metadata.json || echo "File not found" echo -e "\n=== Searching for other dependency files ===" fd -t f "package.json|dependencies.json|deps.json" fhir-info-gateway/ echo -e "\n=== Checking for dependency references in yaml files ===" rg -l "mpi-mediator" -g "*.yaml" -g "*.yml" fhir-info-gateway/Length of output: 1507
interoperability-layer-openhim/docker-compose.yml (1)
28-31
: Verify Keycloak configuration for JWT authentication.The JWT authentication configuration looks secure and well-integrated with Keycloak. However, ensure that:
- The required environment variables (KC_API_URL, KC_REALM_NAME, KC_FRONTEND_URL) are documented
- The setup instructions include steps to configure these in Keycloak
Consider documenting these environment variables in the GitBook documentation under the FHIR Info Gateway package section, as requested in the PR comments.
✅ Verification successful
Environment variables are properly documented ✅
The Keycloak environment variables (KC_API_URL, KC_REALM_NAME, KC_FRONTEND_URL) are well-documented in:
interoperability-layer-openhim/package-metadata.json
identity-access-manager-keycloak/package-metadata.json
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Check if environment variables are documented rg -l "KC_API_URL|KC_REALM_NAME|KC_FRONTEND_URL" documentation/Length of output: 65
Script:
#!/bin/bash # Check for environment variables in README files and env examples echo "=== Searching in README files ===" rg -i "keycloak|environment|env|KC_" README.md **/README.md echo -e "\n=== Searching for .env files ===" fd -g "*.env*" echo -e "\n=== Checking Keycloak setup documentation ===" rg -l "keycloak" .Length of output: 3795
Script:
#!/bin/bash # Check package metadata and env files for Keycloak configuration echo "=== OpenHIM Package Metadata ===" cat interoperability-layer-openhim/package-metadata.json echo -e "\n=== Keycloak Package Metadata ===" cat identity-access-manager-keycloak/package-metadata.json echo -e "\n=== Environment Files Content ===" cat *.env | grep -i "KC_"Length of output: 5399
Hi @rcrichton documentation has been added to the PR with instructions on how to setup the package https://github.com/jembi/platform/blob/09e829d3b16ce6559829c9a0ae5b087f3324923b/documentation/packages/fhir-info-gateway/README.md . The keycloak configurations are automatically created during the init process by a js and json data pre-defined with the necessary clients, scopes and groups. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (2)
documentation/packages/fhir-info-gateway/README.md (2)
13-16
: Enhance overview with architecture diagram and FHIR version support.The overview would benefit from:
- An architecture diagram showing the interactions between OpenHIM, Keycloak, and the FHIR Info Gateway.
- Explicit mention of supported FHIR version(s) for compatibility assessment.
132-138
: Update References section.
- Remove the duplicate initialization command (already shown in System Configuration)
- Add specific references:
- Link to FHIR specification version
- Link to OpenHIM documentation
- Link to Keycloak documentation
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (6)
documentation/packages/fhir-info-gateway/images/GeneratingClientCredentials.png
is excluded by!**/*.png
documentation/packages/fhir-info-gateway/images/NewClient.png
is excluded by!**/*.png
documentation/packages/fhir-info-gateway/images/RouteConfiguration.png
is excluded by!**/*.png
documentation/packages/fhir-info-gateway/images/screenshot-localhost_9088-2024_12_17-14_16_13 (1).png
is excluded by!**/*.png
documentation/packages/fhir-info-gateway/images/screenshot-localhost_9088-2024_12_17-14_48_35 (1).png
is excluded by!**/*.png
documentation/packages/fhir-info-gateway/images/userUuid.png
is excluded by!**/*.png
📒 Files selected for processing (1)
documentation/packages/fhir-info-gateway/README.md
(1 hunks)
🔇 Additional comments (3)
documentation/packages/fhir-info-gateway/README.md (3)
51-51
: Add detailed OpenHIM channel configuration steps.The placeholder comment needs to be replaced with specific configuration details as previously requested.
61-61
: Verify referenced images exist in the repository.The following images are referenced but may not exist:
images/userUuid.png
images/NewClient.png
images/GeneratingClientCredentials.png
Please ensure these images are included in the PR.
Also applies to: 68-68, 82-82
74-78
: Update client credentials example with error handling.The current example needs error handling guidance:
- Common error responses and their solutions
- Troubleshooting steps for authentication failures
| Variable | Description | Example Value | | ||
| ------------------ | --------------------------------------- | --------------------------- | | ||
| `ACCESS_CHECKER` | Enables role-based scope checking | `scope` | | ||
| `REALM_URL` | Keycloak realm URL for token generation | `http://localhost:9088` | | ||
| `GATEWAY_ENDPOINT` | Endpoint for FHIR Info Gateway API | `http://localhost:8080/api` | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance environment variables documentation.
The environment variables table should include:
- Required/Optional status for each variable
- Validation rules (e.g., valid values for
ACCESS_CHECKER
) - Security implications (e.g., HTTPS requirements for
REALM_URL
)
### Disabling Authentication (Development Only) | ||
|
||
- Allow anonymous access via Keycloak settings. | ||
- Update the OpenHIM channel to bypass authentication temporarily. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add security warning for development settings.
The "Disabling Authentication" section needs a prominent security warning:
- Emphasize this is strictly for development environments
- Warn against using these settings in production
- Add steps to re-enable authentication
```bash | ||
curl -X GET \ | ||
-H "Authorization: Bearer <token>" \ | ||
"http://localhost:5001/fhir/Encounter" | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance API testing documentation.
The example request needs:
- List of available endpoints and their purposes
- Expected response formats and examples
- Common error codes and their meanings
- Request/response validation against FHIR specifications
Summary by CodeRabbit
Infrastructure
Documentation
Configuration