Skip to content
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

keycloak: Add option to create authentication sub-flow of type 'form flow' #6318

Merged
merged 9 commits into from
Apr 22, 2023
5 changes: 5 additions & 0 deletions changelogs/fragments/6318-add-form-flow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
bugfixes:
- "keycloak - improve error messages (https://github.com/ansible-collections/community.general/pull/6318)."

minor_changes:
- "keycloak_authentication - add flow type option to sub flows to allow the creation of 'form-flow' sub flows like in Keycloak's built-in registration flow (https://github.com/ansible-collections/community.general/pull/6318)."
12 changes: 9 additions & 3 deletions plugins/module_utils/identity/keycloak/keycloak.py
Original file line number Diff line number Diff line change
Expand Up @@ -1795,6 +1795,9 @@ def update_authentication_executions(self, flowAlias, updatedExec, realm='master
data=json.dumps(updatedExec),
timeout=self.connection_timeout,
validate_certs=self.validate_certs)
except HTTPError as e:
self.module.fail_json(msg="Unable to update execution '%s': %s: %s %s" %
(flowAlias, repr(e), ";".join([e.url, e.msg, str(e.code), str(e.hdrs)]), str(updatedExec)))
except Exception as e:
self.module.fail_json(msg="Unable to update executions %s: %s" % (updatedExec, str(e)))

Expand All @@ -1819,7 +1822,7 @@ def add_authenticationConfig_to_execution(self, executionId, authenticationConfi
except Exception as e:
self.module.fail_json(msg="Unable to add authenticationConfig %s: %s" % (executionId, str(e)))

def create_subflow(self, subflowName, flowAlias, realm='master'):
def create_subflow(self, subflowName, flowAlias, realm='master', flowType='basic-flow'):
""" Create new sublow on the flow

:param subflowName: name of the subflow to create
Expand All @@ -1830,7 +1833,7 @@ def create_subflow(self, subflowName, flowAlias, realm='master'):
newSubFlow = {}
newSubFlow["alias"] = subflowName
newSubFlow["provider"] = "registration-page-form"
newSubFlow["type"] = "basic-flow"
newSubFlow["type"] = flowType
open_url(
URL_AUTHENTICATION_FLOW_EXECUTIONS_FLOW.format(
url=self.baseurl,
Expand Down Expand Up @@ -1865,8 +1868,11 @@ def create_execution(self, execution, flowAlias, realm='master'):
data=json.dumps(newExec),
timeout=self.connection_timeout,
validate_certs=self.validate_certs)
except HTTPError as e:
self.module.fail_json(msg="Unable to create new execution '%s' %s: %s: %s %s" %
(flowAlias, execution["providerId"], repr(e), ";".join([e.url, e.msg, str(e.code), str(e.hdrs)]), str(newExec)))
except Exception as e:
self.module.fail_json(msg="Unable to create new execution %s: %s" % (execution["provider"], str(e)))
self.module.fail_json(msg="Unable to create new execution '%s' %s: %s" % (flowAlias, execution["providerId"], repr(e)))

def change_execution_priority(self, executionId, diff, realm='master'):
""" Raise or lower execution priority of diff time
Expand Down
15 changes: 12 additions & 3 deletions plugins/modules/keycloak_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@
description:
- Priority order of the execution.
type: int
subFlowType:
description:
- For new subflows, optionally specify the type.
flyingflo marked this conversation as resolved.
Show resolved Hide resolved
- Is only used at creation.
choices: ["basic-flow", "form-flow"]
default: "basic-flow"
type: str
flyingflo marked this conversation as resolved.
Show resolved Hide resolved
version_added: 6.6.0
state:
description:
- Control if the authentication flow must exists or not.
Expand Down Expand Up @@ -264,7 +272,7 @@ def create_or_update_executions(kc, config, realm='master'):
exec_index = find_exec_in_executions(new_exec, existing_executions)
if exec_index != -1:
# Remove key that doesn't need to be compared with existing_exec
exclude_key = ["flowAlias"]
exclude_key = ["flowAlias", "subFlowType"]
for index_key, key in enumerate(new_exec, start=0):
if new_exec[key] is None:
exclude_key.append(key)
Expand All @@ -282,7 +290,7 @@ def create_or_update_executions(kc, config, realm='master'):
id_to_update = kc.get_executions_representation(config, realm=realm)[exec_index]["id"]
after += str(new_exec) + '\n'
elif new_exec["displayName"] is not None:
kc.create_subflow(new_exec["displayName"], flow_alias_parent, realm=realm)
kc.create_subflow(new_exec["displayName"], flow_alias_parent, realm=realm, flowType=new_exec["subFlowType"])
exec_found = True
exec_index = new_exec_index
id_to_update = kc.get_executions_representation(config, realm=realm)[exec_index]["id"]
Expand All @@ -299,7 +307,7 @@ def create_or_update_executions(kc, config, realm='master'):
kc.add_authenticationConfig_to_execution(updated_exec["id"], new_exec["authenticationConfig"], realm=realm)
for key in new_exec:
# remove unwanted key for the next API call
if key != "flowAlias" and key != "authenticationConfig":
if key not in ("flowAlias", "authenticationConfig", "subFlowType"):
updated_exec[key] = new_exec[key]
if new_exec["requirement"] is not None:
kc.update_authentication_executions(flow_alias_parent, updated_exec, realm=realm)
Expand Down Expand Up @@ -334,6 +342,7 @@ def main():
flowAlias=dict(type='str'),
authenticationConfig=dict(type='dict'),
index=dict(type='int'),
subFlowType=dict(choices=["basic-flow", "form-flow"], default='basic-flow', type='str'),
)),
state=dict(choices=["absent", "present"], default='present'),
force=dict(type='bool', default=False),
Expand Down