From 107bb744f55b8544f07424efdf5bc0512e17fe7d Mon Sep 17 00:00:00 2001 From: shloka-bhalgat-unskript <110628398+shloka-bhalgat-unskript@users.noreply.github.com> Date: Wed, 11 Oct 2023 10:01:08 +0530 Subject: [PATCH] Keycloak legos (#889) --- Keycloak/__init__.py | 0 .../legos/keycloak_get_audit_report/README.md | 22 ++++++++ .../keycloak_get_audit_report/__init__.py | 0 .../keycloak_get_audit_report.json | 12 +++++ .../keycloak_get_audit_report.py | 53 +++++++++++++++++++ Keycloak/legos/keycloak_get_handle/README.md | 25 +++++++++ .../legos/keycloak_get_handle/__init__.py | 0 .../keycloak_get_handle.json | 11 ++++ .../keycloak_get_handle.py | 17 ++++++ .../keycloak_get_service_health/README.md | 22 ++++++++ .../keycloak_get_service_health/__init__.py | 0 .../keycloak_get_service_health.json | 16 ++++++ .../keycloak_get_service_health.py | 44 +++++++++++++++ 13 files changed, 222 insertions(+) create mode 100644 Keycloak/__init__.py create mode 100644 Keycloak/legos/keycloak_get_audit_report/README.md create mode 100644 Keycloak/legos/keycloak_get_audit_report/__init__.py create mode 100644 Keycloak/legos/keycloak_get_audit_report/keycloak_get_audit_report.json create mode 100644 Keycloak/legos/keycloak_get_audit_report/keycloak_get_audit_report.py create mode 100644 Keycloak/legos/keycloak_get_handle/README.md create mode 100644 Keycloak/legos/keycloak_get_handle/__init__.py create mode 100644 Keycloak/legos/keycloak_get_handle/keycloak_get_handle.json create mode 100644 Keycloak/legos/keycloak_get_handle/keycloak_get_handle.py create mode 100644 Keycloak/legos/keycloak_get_service_health/README.md create mode 100644 Keycloak/legos/keycloak_get_service_health/__init__.py create mode 100644 Keycloak/legos/keycloak_get_service_health/keycloak_get_service_health.json create mode 100644 Keycloak/legos/keycloak_get_service_health/keycloak_get_service_health.py diff --git a/Keycloak/__init__.py b/Keycloak/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/Keycloak/legos/keycloak_get_audit_report/README.md b/Keycloak/legos/keycloak_get_audit_report/README.md new file mode 100644 index 000000000..ae099f6bf --- /dev/null +++ b/Keycloak/legos/keycloak_get_audit_report/README.md @@ -0,0 +1,22 @@ +[] +(https://unskript.com/assets/favicon.png) +

Get Keycloak audit report

+ +## Description +Fetches the audit events from Keycloak. + +## Lego Details + keycloak_get_audit_report(handle): + handle: Handle object containing the KeycloakAdmin instance. + + +## Lego Input +This Lego takes inputs handle. + +## Lego Output +Here is a sample output. + + +## See it in Action + +You can see this Lego in action following this link [unSkript Live](https://us.app.unskript.io) \ No newline at end of file diff --git a/Keycloak/legos/keycloak_get_audit_report/__init__.py b/Keycloak/legos/keycloak_get_audit_report/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/Keycloak/legos/keycloak_get_audit_report/keycloak_get_audit_report.json b/Keycloak/legos/keycloak_get_audit_report/keycloak_get_audit_report.json new file mode 100644 index 000000000..93a3a6e74 --- /dev/null +++ b/Keycloak/legos/keycloak_get_audit_report/keycloak_get_audit_report.json @@ -0,0 +1,12 @@ +{ + "action_title": "Get Keycloak audit report", + "action_description": "Fetches the audit events from Keycloak.", + "action_type": "LEGO_TYPE_KEYCLOAK", + "action_entry_function": "keycloak_get_audit_report", + "action_needs_credential": true, + "action_output_type": "ACTION_OUTPUT_TYPE_LIST", + "action_is_check": false, + "action_supports_iteration": true, + "action_supports_poll": true, + "action_categories":["CATEGORY_TYPE_SRE","CATEGORY_TYPE_KEYCLOAK"] + } \ No newline at end of file diff --git a/Keycloak/legos/keycloak_get_audit_report/keycloak_get_audit_report.py b/Keycloak/legos/keycloak_get_audit_report/keycloak_get_audit_report.py new file mode 100644 index 000000000..939654333 --- /dev/null +++ b/Keycloak/legos/keycloak_get_audit_report/keycloak_get_audit_report.py @@ -0,0 +1,53 @@ +# +# Copyright (c) 2023 unSkript.com +# All rights reserved. +# +from typing import List +from tabulate import tabulate +from pydantic import BaseModel + + +class InputSchema(BaseModel): + pass + + +def keycloak_get_audit_report_printer(output): + if not output: + print("No audit events found.") + return + + # Extract relevant event data for tabulation + table_data = [] + for event in output: + table_data.append({ + "Time": event['time'], + "Type": event['type'], + "User ID": event['userId'], + "Client ID": event['clientId'], + "IP Address": event['ipAddress'], + "Error": event.get('error', '') + }) + + # Convert list of dictionaries to tabulated format + headers = ["Time", "Type", "User ID", "Client ID", "IP Address", "Error"] + print(tabulate(table_data, headers=headers, tablefmt="grid")) + + +def keycloak_get_audit_report(handle) -> List: + """ + keycloak_get_audit_report fetches the audit events from Keycloak. + + :type handle: KeycloakAdmin + :param handle: Handle containing the KeycloakAdmin instance. + + :rtype: List of dictionaries representing the audit events. + """ + try: + # Fetch the events + events = handle.get_events() + return events if events else [] + + except Exception as e: + raise e + + diff --git a/Keycloak/legos/keycloak_get_handle/README.md b/Keycloak/legos/keycloak_get_handle/README.md new file mode 100644 index 000000000..2e4556786 --- /dev/null +++ b/Keycloak/legos/keycloak_get_handle/README.md @@ -0,0 +1,25 @@ +[](https://unskript.com/assets/favicon.png) +

Get Keycloak Handle

+ +
+ +## Description +This Lego Get Keycloak Handle. + + +## Lego Details + + keycloak_get_handle(handle: object) + + handle: Object of type unSkript Keycloak Connector + +## Lego Input +This Lego take one input handle. + +## Lego Output +Here is a sample output. + + +## See it in Action + +You can see this Lego in action following this link [unSkript Live](https://us.app.unskript.io) \ No newline at end of file diff --git a/Keycloak/legos/keycloak_get_handle/__init__.py b/Keycloak/legos/keycloak_get_handle/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/Keycloak/legos/keycloak_get_handle/keycloak_get_handle.json b/Keycloak/legos/keycloak_get_handle/keycloak_get_handle.json new file mode 100644 index 000000000..b1e5942c3 --- /dev/null +++ b/Keycloak/legos/keycloak_get_handle/keycloak_get_handle.json @@ -0,0 +1,11 @@ +{ + "action_title": "Keycloak Get Handle", + "action_description": "Get Keycloak Handle", + "action_type": "LEGO_TYPE_KEYCLOAK", + "action_entry_function": "keycloak_get_handle", + "action_needs_credential": true, + "action_supports_poll": false, + "action_supports_iteration": false, + "action_output_type": "ACTION_OUTPUT_TYPE_LIST" +} + \ No newline at end of file diff --git a/Keycloak/legos/keycloak_get_handle/keycloak_get_handle.py b/Keycloak/legos/keycloak_get_handle/keycloak_get_handle.py new file mode 100644 index 000000000..e9f21a1a9 --- /dev/null +++ b/Keycloak/legos/keycloak_get_handle/keycloak_get_handle.py @@ -0,0 +1,17 @@ +## +## Copyright (c) 2023 unSkript, Inc +## All rights reserved. +## +from pydantic import BaseModel + + +class InputSchema(BaseModel): + pass + + +def keycloak_get_handle(handle): + """keycloak_get_handle returns the Keycloak handle. + + :rtype: Keycloak handle. + """ + return handle diff --git a/Keycloak/legos/keycloak_get_service_health/README.md b/Keycloak/legos/keycloak_get_service_health/README.md new file mode 100644 index 000000000..724039c95 --- /dev/null +++ b/Keycloak/legos/keycloak_get_service_health/README.md @@ -0,0 +1,22 @@ +[] +(https://unskript.com/assets/favicon.png) +

Get Keycloak service health

+ +## Description +Fetches the health of the Keycloak service by trying to list available realms. + +## Lego Details + keycloak_get_service_health fetches the health of the Keycloak service by trying to list available realms. + handle: Handle containing the KeycloakAdmin instance. + + +## Lego Input +This Lego takes inputs handle. + +## Lego Output +Here is a sample output. + + +## See it in Action + +You can see this Lego in action following this link [unSkript Live](https://us.app.unskript.io) \ No newline at end of file diff --git a/Keycloak/legos/keycloak_get_service_health/__init__.py b/Keycloak/legos/keycloak_get_service_health/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/Keycloak/legos/keycloak_get_service_health/keycloak_get_service_health.json b/Keycloak/legos/keycloak_get_service_health/keycloak_get_service_health.json new file mode 100644 index 000000000..8bd9c9344 --- /dev/null +++ b/Keycloak/legos/keycloak_get_service_health/keycloak_get_service_health.json @@ -0,0 +1,16 @@ +{ + "action_title": "Get Keycloak service health", + "action_description": "Fetches the health of the Keycloak service by trying to list available realms.", + "action_type": "LEGO_TYPE_KEYCLOAK", + "action_entry_function": "keycloak_get_service_health", + "action_needs_credential": true, + "action_output_type": "ACTION_OUTPUT_TYPE_LIST", + "action_is_check": true, + "action_next_hop": [ + "" + ], + "action_next_hop_parameter_mapping": {}, + "action_supports_iteration": true, + "action_supports_poll": true, + "action_categories":["CATEGORY_TYPE_SRE","CATEGORY_TYPE_KEYCLOAK"] + } \ No newline at end of file diff --git a/Keycloak/legos/keycloak_get_service_health/keycloak_get_service_health.py b/Keycloak/legos/keycloak_get_service_health/keycloak_get_service_health.py new file mode 100644 index 000000000..edf85be34 --- /dev/null +++ b/Keycloak/legos/keycloak_get_service_health/keycloak_get_service_health.py @@ -0,0 +1,44 @@ +# +# Copyright (c) 2023 unSkript.com +# All rights reserved. +# + +from typing import Tuple +from pydantic import BaseModel + + +class InputSchema(BaseModel): + pass + +def keycloak_get_service_health(handle) -> Tuple: + """ + keycloak_get_service_health fetches the health of the Keycloak service by trying to list available realms. + + :type handle: object + :param handle: Handle containing the KeycloakAdmin instance. + + :rtype: Tuple indicating if the service is healthy and a list of available realms (or None if healthy). + """ + try: + realms = handle.get_realms() + available_realms = [realm["realm"] for realm in realms] + + if not available_realms: + return (False, available_realms) + + return (True, None) + + except Exception as e: + raise e + +def keycloak_get_service_health_printer(output): + is_healthy, realms = output + + if is_healthy: + print("Keycloak Service is Healthy.") + else: + print("Keycloak Service is Unhealthy.") + if realms: + print("\nUnavailable Realms:") + for realm in realms: + print(f" - {realm}")