From 42b01570ae4580991fee98d5e3adfa6c74402a54 Mon Sep 17 00:00:00 2001 From: pa1narendra Date: Fri, 6 Sep 2024 10:13:18 +0000 Subject: [PATCH] feat(auth): added keycloak as a social login provider --- .../social_login_key/social_login_key.json | 6 ++--- .../social_login_key/social_login_key.py | 26 ++++++++++++++++++- frappe/integrations/oauth2_logins.py | 5 ++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/frappe/integrations/doctype/social_login_key/social_login_key.json b/frappe/integrations/doctype/social_login_key/social_login_key.json index d555eb04bb..55c9f96abb 100644 --- a/frappe/integrations/doctype/social_login_key/social_login_key.json +++ b/frappe/integrations/doctype/social_login_key/social_login_key.json @@ -52,7 +52,7 @@ "fieldname": "social_login_provider", "fieldtype": "Select", "label": "Social Login Provider", - "options": "Custom\nFacebook\nFrappe\nGitHub\nGoogle\nOffice 365\nSalesforce\nfairlogin", + "options": "Custom\nFacebook\nFrappe\nGitHub\nGoogle\nOffice 365\nSalesforce\nfairlogin\nKeycloak", "set_only_once": 1 }, { @@ -176,7 +176,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2024-03-23 16:03:38.963265", + "modified": "2024-09-06 15:22:46.342392", "modified_by": "Administrator", "module": "Integrations", "name": "Social Login Key", @@ -200,4 +200,4 @@ "states": [], "title_field": "provider_name", "track_changes": 1 -} +} \ No newline at end of file diff --git a/frappe/integrations/doctype/social_login_key/social_login_key.py b/frappe/integrations/doctype/social_login_key/social_login_key.py index 8dbea0ae55..6f65c2c642 100644 --- a/frappe/integrations/doctype/social_login_key/social_login_key.py +++ b/frappe/integrations/doctype/social_login_key/social_login_key.py @@ -56,7 +56,15 @@ class SocialLoginKey(Document): redirect_url: DF.Data | None sign_ups: DF.Literal["", "Allow", "Deny"] social_login_provider: DF.Literal[ - "Custom", "Facebook", "Frappe", "GitHub", "Google", "Office 365", "Salesforce", "fairlogin" + "Custom", + "Facebook", + "Frappe", + "GitHub", + "Google", + "Office 365", + "Salesforce", + "fairlogin", + "Keycloak", ] user_id_property: DF.Data | None # end: auto-generated types @@ -80,6 +88,8 @@ class SocialLoginKey(Document): frappe.throw( _("Please enter Client Secret before social login is enabled"), exc=ClientSecretNotSetError ) + if self.social_login_provider == "Keycloak": + self.api_endpoint = self.base_url + "/protocol/openid-connect/userinfo" def set_icon(self): icon_map = { @@ -206,6 +216,20 @@ class SocialLoginKey(Document): "auth_url_data": json.dumps({"response_type": "code", "scope": "openid"}), } + providers["Keycloak"] = { + "provider_name": "Keycloak", + "enable_social_login": 1, + "base_url": "realms/master", + "custom_base_url": 1, + "redirect_url": "/api/method/frappe.integrations.oauth2_logins.login_via_keycloak/keycloak", + "api_endpoint": "realms/masterl/protocol/openid-connect/userinfo", + "api_endpoint_args": None, + "authorize_url": "/protocol/openid-connect/auth", + "access_token_url": "/protocol/openid-connect/token", + "user_id_property": "preferred_username", + "auth_url_data": json.dumps({"response_type": "code", "scope": "openid"}), + } + # Initialize the doc and return, used in patch # Or can be used for creating key from controller if initialize and provider: diff --git a/frappe/integrations/oauth2_logins.py b/frappe/integrations/oauth2_logins.py index 942ad2b51b..e4549c8ec6 100644 --- a/frappe/integrations/oauth2_logins.py +++ b/frappe/integrations/oauth2_logins.py @@ -43,6 +43,11 @@ def login_via_fairlogin(code: str, state: str): login_via_oauth2("fairlogin", code, state, decoder=decoder_compat) +@frappe.whitelist(allow_guest=True) +def login_via_keycloak(code: str, state: str): + login_via_oauth2("keycloak", code, state, decoder=decoder_compat) + + @frappe.whitelist(allow_guest=True) def custom(code: str, state: str): """