From 0bdd508b1e0928d999e47cc4ba80b5939f379383 Mon Sep 17 00:00:00 2001 From: Wambere Date: Tue, 20 Feb 2024 20:17:33 +0300 Subject: [PATCH] pass access token via the config file (#145) * pass access token via the config file * Pass access token as command line option --- importer/README.md | 2 +- importer/main.py | 60 +++++++++++++++++++++++++++------------ importer/sample_config.py | 1 + 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/importer/README.md b/importer/README.md index 46438c8b..8f4d24b1 100644 --- a/importer/README.md +++ b/importer/README.md @@ -17,7 +17,7 @@ This script is used to setup keycloak roles and groups. It takes in a csv file w ### To run script 1. Create virtualenv 2. Install requirements.txt - `pip install -r requirements.txt` -3. Create a `config.py` file. The `sample_config.py` is an example of what this should look like. Populate it with the right credentials. Ensure that the user whose details you provide in this config file has the necessary permissions/privilleges to setup/create Keycloak roles and groups. +3. Create a `config.py` file. The `sample_config.py` is an example of what this should look like. Populate it with the right credentials, you can either provide an access token or client credentials. Ensure that the user whose details you provide in this config file has the necessary permissions/privilleges. 4. Run script - `python3 main.py --setup roles --csv_file csv/setup/roles.csv --group Supervisor` 5. If you are running the script without `https` setup e.g locally or a server without https setup, you will need to set the `OAUTHLIB_INSECURE_TRANSPORT` environment variable to 1. For example `export OAUTHLIB_INSECURE_TRANSPORT=1 && python3 main.py --setup roles --csv_file csv/setup/roles.csv --group OpenSRP_Provider --log_level debug` 6. You can turn on logging by passing a `--log_level` to the command line as `info`, `debug` or `error`. For example `python3 main.py --setup roles --csv_file csv/setup/roles.csv --group Supervisor --log_level debug` diff --git a/importer/main.py b/importer/main.py index 2a36c88c..3d356cae 100644 --- a/importer/main.py +++ b/importer/main.py @@ -15,6 +15,7 @@ logging.error("The config.py file is missing!") exit() +global_access_token = "" # This function takes in a csv file # reads it and returns a list of strings/lines @@ -37,6 +38,39 @@ def read_csv(csv_file): logging.error("Stop iteration on empty file") +def get_access_token(): + access_token = "" + if global_access_token: + return global_access_token + + try: + if config.access_token: + # get access token from config file + access_token = config.access_token + except AttributeError: + logging.debug("No access token provided, trying to use client credentials") + + if not access_token: + # get client credentials from config file + client_id = config.client_id + client_secret = config.client_secret + username = config.username + password = config.password + access_token_url = config.access_token_url + + oauth = OAuth2Session(client=LegacyApplicationClient(client_id=client_id)) + token = oauth.fetch_token( + token_url=access_token_url, + username=username, + password=password, + client_id=client_id, + client_secret=client_secret, + ) + access_token = token["access_token"] + + return access_token + + # This function makes the request to the provided url # to create resources @backoff.on_exception(backoff.expo, requests.exceptions.RequestException, max_time=180) @@ -46,23 +80,7 @@ def post_request(request_type, payload, url): logging.info("Url: " + url) logging.debug("Payload: " + payload) - # get credentials from config file - client_id = config.client_id - client_secret = config.client_secret - username = config.username - password = config.password - access_token_url = config.access_token_url - - oauth = OAuth2Session(client=LegacyApplicationClient(client_id=client_id)) - token = oauth.fetch_token( - token_url=access_token_url, - username=username, - password=password, - client_id=client_id, - client_secret=client_secret, - ) - - access_token = "Bearer " + token["access_token"] + access_token = "Bearer " + get_access_token() headers = {"Content-type": "application/json", "Authorization": access_token} if request_type == "POST": @@ -845,6 +863,7 @@ def clean_duplicates(users, cascade_delete): @click.command() @click.option("--csv_file", required=True) +@click.option("--access_token", required=False) @click.option("--resource_type", required=False) @click.option("--assign", required=False) @click.option("--setup", required=False) @@ -855,7 +874,7 @@ def clean_duplicates(users, cascade_delete): "--log_level", type=click.Choice(["DEBUG", "INFO", "ERROR"], case_sensitive=False) ) def main( - csv_file, resource_type, assign, setup, group, roles_max, cascade_delete, log_level + csv_file, access_token, resource_type, assign, setup, group, roles_max, cascade_delete, log_level ): if log_level == "DEBUG": logging.basicConfig(level=logging.DEBUG) @@ -867,6 +886,11 @@ def main( start_time = datetime.now() logging.info("Start time: " + start_time.strftime("%H:%M:%S")) + # set access token + if access_token: + global global_access_token + global_access_token = access_token + logging.info("Starting csv import...") resource_list = read_csv(csv_file) if resource_list: diff --git a/importer/sample_config.py b/importer/sample_config.py index f2642368..d46cc9ac 100644 --- a/importer/sample_config.py +++ b/importer/sample_config.py @@ -5,3 +5,4 @@ access_token_url = 'https://keycloak.smartregister.org/auth/realms/example-realm/protocol/openid-connect/token' fhir_base_url = 'https://example.smartregister.org/fhir' keycloak_url = 'https://keycloak.smartregister.org/auth/admin/realms/example-realm' +access_token = 'example-access-token'