From 826f31acf6b0f673bd1cf725b3ad08ccef7a1b06 Mon Sep 17 00:00:00 2001 From: hilary egesa Date: Fri, 26 Apr 2024 15:36:26 +0300 Subject: [PATCH 01/13] init multifactor authentication setup --- importer/main.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/importer/main.py b/importer/main.py index 5a421198..a80605b6 100644 --- a/importer/main.py +++ b/importer/main.py @@ -1301,6 +1301,13 @@ def main( click.confirm("Do you want to continue?", abort=True) clean_duplicates(resource_list, cascade_delete) logging.info("Processing complete!") + elif setup == "multifactor_authenticaton": + logging.info("=========================================") + logging.info( + "You are about to add multifactor authentication to keycloak" + ) + click.confirm("Do you want to continue?", abort=True) + logging.info("Processing complete!") else: logging.error("Unsupported request!") else: From a0e37aa636ef473d44b87bff5df3b8aa1b4501bb Mon Sep 17 00:00:00 2001 From: hilary egesa Date: Fri, 26 Apr 2024 15:39:00 +0300 Subject: [PATCH 02/13] Revert "init multifactor authentication setup" This reverts commit 826f31acf6b0f673bd1cf725b3ad08ccef7a1b06. --- importer/main.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/importer/main.py b/importer/main.py index a80605b6..5a421198 100644 --- a/importer/main.py +++ b/importer/main.py @@ -1301,13 +1301,6 @@ def main( click.confirm("Do you want to continue?", abort=True) clean_duplicates(resource_list, cascade_delete) logging.info("Processing complete!") - elif setup == "multifactor_authenticaton": - logging.info("=========================================") - logging.info( - "You are about to add multifactor authentication to keycloak" - ) - click.confirm("Do you want to continue?", abort=True) - logging.info("Processing complete!") else: logging.error("Unsupported request!") else: From 6b276cde81bf674a74cfa8d07787f6ab3f1cdd8c Mon Sep 17 00:00:00 2001 From: hilary egesa Date: Fri, 26 Apr 2024 15:54:48 +0300 Subject: [PATCH 03/13] init multifactor authentication setup --- importer/main.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/importer/main.py b/importer/main.py index 5a421198..d05c3253 100644 --- a/importer/main.py +++ b/importer/main.py @@ -1301,6 +1301,13 @@ def main( click.confirm("Do you want to continue?", abort=True) clean_duplicates(resource_list, cascade_delete) logging.info("Processing complete!") + elif setup == "multifactor_authenticaton": + logging.info("=========================================") + logging.info( + "You are about to add multifactor authentication to Keycloak" + ) + click.confirm("Do you want to continue?", abort=True) + logging.info("Processing complete!") else: logging.error("Unsupported request!") else: From db206fc7039085fcf848cf767a142dd21c4abf08 Mon Sep 17 00:00:00 2001 From: hilary egesa Date: Thu, 22 Aug 2024 12:03:48 +0300 Subject: [PATCH 04/13] add env.example file --- importer/.env.example | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 importer/.env.example diff --git a/importer/.env.example b/importer/.env.example new file mode 100644 index 00000000..e69de29b From d9f09c150b3b6f779f52c775c315f33e2de01366 Mon Sep 17 00:00:00 2001 From: hilary egesa Date: Wed, 28 Aug 2024 15:28:30 +0300 Subject: [PATCH 05/13] test otp endpoints --- importer/.env.example | 10 ++++++++++ importer/main.py | 25 ++++++++++++++++--------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/importer/.env.example b/importer/.env.example index e69de29b..6c89b85e 100644 --- a/importer/.env.example +++ b/importer/.env.example @@ -0,0 +1,10 @@ +client_id='' +client_secret='' +fhir_base_url='' +keycloak_url='' +realm='' +product_access_token='' +username='' +password='' +access_token='' +refresh_token='' \ No newline at end of file diff --git a/importer/main.py b/importer/main.py index 467e32a7..ebc8a1d7 100644 --- a/importer/main.py +++ b/importer/main.py @@ -66,6 +66,7 @@ def filter(self, record): @click.option("--chunk_size", required=False, default=1000000) @click.option("--resources_count", required=False, default=100) @click.option("--list_resource_id", required=False) +@click.option("--multifactor_authenticaton", required=False, is_flag=True) @click.option( "--log_level", type=click.Choice(["DEBUG", "INFO", "ERROR"], case_sensitive=False) ) @@ -144,9 +145,9 @@ def main( logging.info("Starting csv import...") json_path = "/".join([dir_path, "json_payloads/"]) - resource_list = read_csv(csv_file) - if resource_list: + if csv_file is not None: + resource_list = read_csv(csv_file) if resource_type == "users": logging.info("Processing users") with click.progressbar( @@ -223,13 +224,6 @@ def main( click.confirm("Do you want to continue?", abort=True) clean_duplicates(resource_list, cascade_delete) logging.info("Processing complete!") - elif setup == "multifactor_authenticaton": - logging.info("=========================================") - logging.info( - "You are about to add multifactor authentication to Keycloak" - ) - click.confirm("Do you want to continue?", abort=True) - logging.info("Processing complete!") elif setup == "products": logging.info("Importing products as FHIR Group resources") json_payload, created_resources = build_payload( @@ -288,6 +282,19 @@ def main( logging.error("Unsupported request!") else: logging.error("Empty csv file!") + if multifactor_authenticaton is not None: + # get details + response = handle_request( + "GET",payload = "", url="http://localhost:8082/admin/realms/master" + ) + logging.error(response[0]) + + respons = handle_request( + "PUT",payload = response[0], url="http://localhost:8082/admin/realms/master/authentication/flows/browser/executions" + ) + + logging.error(respons) + if final_response and final_response.text: logging.info('{ "final-response": ' + final_response.text + "}") From 2d6067a3662da15253f1ad7294745b9a349265d1 Mon Sep 17 00:00:00 2001 From: hilary egesa Date: Thu, 28 Nov 2024 16:13:59 +0300 Subject: [PATCH 06/13] get and update otp execution flow --- importer/main.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/importer/main.py b/importer/main.py index ebc8a1d7..1d3d9ee0 100644 --- a/importer/main.py +++ b/importer/main.py @@ -2,6 +2,7 @@ import logging.config import pathlib from datetime import datetime +import json import click @@ -12,7 +13,7 @@ from importer.request import handle_request from importer.users import (assign_default_groups_roles, assign_group_roles, confirm_keycloak_user, confirm_practitioner, - create_roles, create_user, create_user_resources) + create_roles, create_user, create_user_resources, keycloak_url) from importer.utils import (build_mapped_payloads, clean_duplicates, export_resources_to_csv, read_csv, read_file_in_chunks) @@ -103,6 +104,7 @@ def main( list_resource_id, sync, location_type_coding_system, + multifactor_authenticaton ): if log_level == "DEBUG": logging.basicConfig( @@ -285,15 +287,20 @@ def main( if multifactor_authenticaton is not None: # get details response = handle_request( - "GET",payload = "", url="http://localhost:8082/admin/realms/master" + "GET",payload = "", url = keycloak_url+"/admin/realms/master/authentication/flows/browser/executions" ) - logging.error(response[0]) + target_display_name = "Browser - Conditional OTP" + data = json.loads(response[0]) + + result = next((item for item in data if item["displayName"] == target_display_name), None) + result["requirement"] = "REQUIRED" + parsed_payload = json.dumps(result) respons = handle_request( - "PUT",payload = response[0], url="http://localhost:8082/admin/realms/master/authentication/flows/browser/executions" + "PUT",payload = parsed_payload, url = keycloak_url+"/admin/realms/master/authentication/flows/browser/executions" ) - - logging.error(respons) + logging.info(respons) + if final_response and final_response.text: From 08ca95deca5088a9527b1879e62585fd1544b6bb Mon Sep 17 00:00:00 2001 From: hilary egesa Date: Fri, 29 Nov 2024 17:55:36 +0300 Subject: [PATCH 07/13] refactor variable names --- importer/main.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/importer/main.py b/importer/main.py index 1d3d9ee0..7504aee3 100644 --- a/importer/main.py +++ b/importer/main.py @@ -67,7 +67,7 @@ def filter(self, record): @click.option("--chunk_size", required=False, default=1000000) @click.option("--resources_count", required=False, default=100) @click.option("--list_resource_id", required=False) -@click.option("--multifactor_authenticaton", required=False, is_flag=True) +@click.option("--multifactor_authentication", required=False, is_flag=True) @click.option( "--log_level", type=click.Choice(["DEBUG", "INFO", "ERROR"], case_sensitive=False) ) @@ -104,7 +104,7 @@ def main( list_resource_id, sync, location_type_coding_system, - multifactor_authenticaton + multifactor_authentication ): if log_level == "DEBUG": logging.basicConfig( @@ -283,23 +283,22 @@ def main( else: logging.error("Unsupported request!") else: - logging.error("Empty csv file!") - if multifactor_authenticaton is not None: + if multifactor_authentication is not None: # get details - response = handle_request( + keyclock_browser_flows_response = handle_request( "GET",payload = "", url = keycloak_url+"/admin/realms/master/authentication/flows/browser/executions" ) target_display_name = "Browser - Conditional OTP" - data = json.loads(response[0]) + data = json.loads(keyclock_browser_flows_response[0]) result = next((item for item in data if item["displayName"] == target_display_name), None) result["requirement"] = "REQUIRED" parsed_payload = json.dumps(result) - respons = handle_request( + update_keycloak_browser_flow_response = handle_request( "PUT",payload = parsed_payload, url = keycloak_url+"/admin/realms/master/authentication/flows/browser/executions" ) - logging.info(respons) + logging.info(update_keycloak_browser_flow_response) From 37f352c0870e4d039a13fc0c339a2195799b5b17 Mon Sep 17 00:00:00 2001 From: hilary egesa Date: Thu, 5 Dec 2024 12:40:32 +0300 Subject: [PATCH 08/13] toggle 2factor auth setting --- importer/main.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/importer/main.py b/importer/main.py index 665daf92..9f76ccff 100644 --- a/importer/main.py +++ b/importer/main.py @@ -306,7 +306,10 @@ def main( data = json.loads(keyclock_browser_flows_response[0]) result = next((item for item in data if item["displayName"] == target_display_name), None) - result["requirement"] = "REQUIRED" + if(result["requirement"]== "ALTERNATIVE"): + result["requirement"] = "REQUIRED" + else: + result["requirement"] = "ALTERNATIVE" parsed_payload = json.dumps(result) update_keycloak_browser_flow_response = handle_request( "PUT",payload = parsed_payload, url = keycloak_url+"/admin/realms/master/authentication/flows/browser/executions" From 0349feeca84bde3ea826432d78f4a1dde339dc12 Mon Sep 17 00:00:00 2001 From: hilary egesa Date: Thu, 5 Dec 2024 15:19:05 +0300 Subject: [PATCH 09/13] update link to efsity-cli in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a49cfca9..7393d867 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ A repo to hold our FHIR content and configuration creation tools and scripts. - [cleaner](https://github.com/onaio/fhircore-tooling/tree/main/cleaner) -- [efsity](https://github.com/onaio/fhircore-tooling/tree/main/efsity) +- [efsity](https://github.com/onaio/fhircore-tooling/tree/main/efsity-cli) - [efsity-ide](https://github.com/onaio/fhircore-tooling/tree/main/efsity-ide) - [importer](https://github.com/onaio/fhircore-tooling/tree/main/importer) - [sm-gen](https://github.com/onaio/fhircore-tooling/tree/main/sm-gen) From 17df51746f8baae7ed39ca4a824416612bf6d64f Mon Sep 17 00:00:00 2001 From: hilary egesa Date: Tue, 10 Dec 2024 15:46:43 +0300 Subject: [PATCH 10/13] fix error with logiging option --- importer/main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/importer/main.py b/importer/main.py index 9f76ccff..8b2d8a70 100644 --- a/importer/main.py +++ b/importer/main.py @@ -82,15 +82,15 @@ def main( ): if log_level == "DEBUG": logging.basicConfig( - filename="importer.log", encoding="utf-8", level=logging.DEBUG + filename="importer.log", level=logging.DEBUG ) elif log_level == "INFO": logging.basicConfig( - filename="importer.log", encoding="utf-8", level=logging.INFO + filename="importer.log", level=logging.INFO ) elif log_level == "ERROR": logging.basicConfig( - filename="importer.log", encoding="utf-8", level=logging.ERROR + filename="importer.log", level=logging.ERROR ) logging.getLogger().addHandler(logging.StreamHandler()) From ad43f198085a445e374bfc46963b23ed1d55fcfd Mon Sep 17 00:00:00 2001 From: hilary egesa Date: Thu, 23 Jan 2025 12:07:05 +0300 Subject: [PATCH 11/13] use get_keycloak_url function --- importer/main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/importer/main.py b/importer/main.py index 8b2d8a70..ce80f6fe 100644 --- a/importer/main.py +++ b/importer/main.py @@ -14,7 +14,7 @@ from importer.request import handle_request from importer.users import (assign_default_groups_roles, assign_group_roles, confirm_keycloak_user, confirm_practitioner, - create_roles, create_user, create_user_resources, keycloak_url) + create_roles, create_user, create_user_resources, get_keycloak_url) from importer.utils import (build_mapped_payloads, clean_duplicates, export_resources_to_csv, read_csv, read_file_in_chunks) @@ -299,7 +299,7 @@ def main( if multifactor_authentication is not None: # get details keyclock_browser_flows_response = handle_request( - "GET",payload = "", url = keycloak_url+"/admin/realms/master/authentication/flows/browser/executions" + "GET",payload = "", url = get_keycloak_url+"/admin/realms/master/authentication/flows/browser/executions" ) target_display_name = "Browser - Conditional OTP" @@ -312,7 +312,7 @@ def main( result["requirement"] = "ALTERNATIVE" parsed_payload = json.dumps(result) update_keycloak_browser_flow_response = handle_request( - "PUT",payload = parsed_payload, url = keycloak_url+"/admin/realms/master/authentication/flows/browser/executions" + "PUT",payload = parsed_payload, url = get_keycloak_url+"/admin/realms/master/authentication/flows/browser/executions" ) logging.info(update_keycloak_browser_flow_response) From dea95e64b1fa9760de7a0e40ab709452d022d0fb Mon Sep 17 00:00:00 2001 From: hilary egesa Date: Thu, 23 Jan 2025 12:38:30 +0300 Subject: [PATCH 12/13] resolve string contact error --- importer/main.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/importer/main.py b/importer/main.py index f9a7237c..2a9f1604 100644 --- a/importer/main.py +++ b/importer/main.py @@ -298,21 +298,22 @@ def main( else: if multifactor_authentication is not None: # get details - keyclock_browser_flows_response = handle_request( - "GET",payload = "", url = get_keycloak_url+"/admin/realms/master/authentication/flows/browser/executions" + keycloack_browser_flows_response = handle_request( + "GET",payload = "", url = get_keycloak_url()+"/admin/realms/master/authentication/flows/browser/executions" ) target_display_name = "Browser - Conditional OTP" - data = json.loads(keyclock_browser_flows_response[0]) + data = json.loads(keycloack_browser_flows_response[0]) result = next((item for item in data if item["displayName"] == target_display_name), None) + # Enable or disable multifactor authentication with OTP if(result["requirement"]== "ALTERNATIVE"): result["requirement"] = "REQUIRED" else: result["requirement"] = "ALTERNATIVE" parsed_payload = json.dumps(result) update_keycloak_browser_flow_response = handle_request( - "PUT",payload = parsed_payload, url = get_keycloak_url+"/admin/realms/master/authentication/flows/browser/executions" + "PUT",payload = parsed_payload, url = get_keycloak_url()+"/admin/realms/master/authentication/flows/browser/executions" ) logging.info(update_keycloak_browser_flow_response) From 31c0881b8b1391204dffd4257a741ca386943b34 Mon Sep 17 00:00:00 2001 From: hilary egesa Date: Thu, 23 Jan 2025 15:59:42 +0300 Subject: [PATCH 13/13] update keycloak endpoint --- importer/main.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/importer/main.py b/importer/main.py index 2a9f1604..e98aafb9 100644 --- a/importer/main.py +++ b/importer/main.py @@ -299,12 +299,11 @@ def main( if multifactor_authentication is not None: # get details keycloack_browser_flows_response = handle_request( - "GET",payload = "", url = get_keycloak_url()+"/admin/realms/master/authentication/flows/browser/executions" + "GET",payload = "", url = get_keycloak_url()+"/authentication/flows/browser/executions" ) target_display_name = "Browser - Conditional OTP" data = json.loads(keycloack_browser_flows_response[0]) - result = next((item for item in data if item["displayName"] == target_display_name), None) # Enable or disable multifactor authentication with OTP if(result["requirement"]== "ALTERNATIVE"): @@ -313,7 +312,7 @@ def main( result["requirement"] = "ALTERNATIVE" parsed_payload = json.dumps(result) update_keycloak_browser_flow_response = handle_request( - "PUT",payload = parsed_payload, url = get_keycloak_url()+"/admin/realms/master/authentication/flows/browser/executions" + "PUT",payload = parsed_payload, url = get_keycloak_url()+"/authentication/flows/browser/executions" ) logging.info(update_keycloak_browser_flow_response)