1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2026-03-22 05:09:12 +00:00

add module keycloak_authentication_v2 (#11557)

* add module keycloak_authentication_v2

* skip sanity checks, because the run into a recursion

* 11556 fix documentation

* 11556 limit the depth of nested flows to 4

* 11556 code cleanup

* 11556 code cleanup - add type hints

* 11556 add keycloak_authentication_v2 to meta/runtime.yml

* 11556 code cleanup - remove custom type hints

* 11556 code cleanup - none checks

* Update plugins/modules/keycloak_authentication_v2.py

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* Update plugins/modules/keycloak_authentication_v2.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* 11556 code cleanup - remove document starts

* 11556 cleanup

* 11556 cleanup

---------

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Thomas Bargetz <thomas.bargetz@rise-world.com>
This commit is contained in:
thomasbargetz 2026-03-12 22:04:08 +01:00 committed by GitHub
parent 0e4783dcc3
commit a69f7e60b4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 1765 additions and 0 deletions

View file

@ -0,0 +1,10 @@
<!--
Copyright (c) Ansible Project
GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
SPDX-License-Identifier: GPL-3.0-or-later
-->
# Running keycloak_authentication_v2 module integration test
Run integration tests:
ansible-test integration -v keycloak_authentication_v2 --allow-unsupported --docker fedora42 --docker-network host

View file

@ -0,0 +1,5 @@
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
unsupported

View file

@ -0,0 +1,24 @@
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
- name: Get access token
ansible.builtin.uri:
url: "{{ url }}/realms/{{ admin_realm }}/protocol/openid-connect/token"
method: POST
status_code: 200
headers:
Accept: application/json
User-agent: Ansible
body_format: form-urlencoded
body:
grant_type: "password"
client_id: "admin-cli"
username: "{{ admin_user }}"
password: "{{ admin_password }}"
register: token_response
no_log: true
- name: Extract access token
ansible.builtin.set_fact:
access_token: "{{ token_response.json['access_token'] }}"
no_log: true

View file

@ -0,0 +1,41 @@
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
- name: Flow Creation/Update <Integration Test Flow> Version 1
community.general.keycloak_authentication_v2:
auth_keycloak_url: "{{ url }}"
auth_realm: "{{ admin_realm }}"
auth_username: "{{ admin_user }}"
auth_password: "{{ admin_password }}"
realm: "{{ realm }}"
alias: Integration Test Flow
state: present
authenticationExecutions:
- providerId: idp-review-profile
requirement: REQUIRED
authenticationConfig:
alias: Integration Test Flow - review profile config
config:
update.profile.on.first.login: "missing"
- subFlow: Integration Test Flow - User creation or linking
requirement: REQUIRED
authenticationExecutions:
- providerId: idp-create-user-if-unique
requirement: ALTERNATIVE
authenticationConfig:
alias: Integration Test Flow - create unique user config
config:
require.password.update.after.registration: "false"
- subFlow: Integration Test Flow - Handle Existing Account
requirement: ALTERNATIVE
authenticationExecutions:
- providerId: idp-confirm-link
requirement: REQUIRED
- providerId: auth-cookie
requirement: REQUIRED
register: flow_v1_result
- name: Expose flow_v1_result to parent scope
ansible.builtin.set_fact:
flow_v1_result: "{{ flow_v1_result }}"
no_log: true

View file

@ -0,0 +1,47 @@
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
# - adding a new execution inside the sub flow 'Integration Test Flow - User creation or linking' after the execution 'idp-create-user-if-unique'
# - disable auth-cookie at the end of the flow
# - change the config require.password.update.after.registration to "true"
- name: Flow Creation/Update <Integration Test Flow> Version 2
community.general.keycloak_authentication_v2:
auth_keycloak_url: "{{ url }}"
auth_realm: "{{ admin_realm }}"
auth_username: "{{ admin_user }}"
auth_password: "{{ admin_password }}"
realm: "{{ realm }}"
alias: Integration Test Flow
state: present
authenticationExecutions:
- providerId: idp-review-profile
requirement: REQUIRED
authenticationConfig:
alias: Integration Test Flow - review profile config
config:
update.profile.on.first.login: "missing"
- subFlow: Integration Test Flow - User creation or linking
requirement: REQUIRED
authenticationExecutions:
- providerId: idp-create-user-if-unique
requirement: ALTERNATIVE
authenticationConfig:
alias: Integration Test Flow - create unique user config
config:
require.password.update.after.registration: "true"
- providerId: auth-cookie
requirement: REQUIRED
- subFlow: Integration Test Flow - Handle Existing Account
requirement: ALTERNATIVE
authenticationExecutions:
- providerId: idp-confirm-link
requirement: REQUIRED
- providerId: auth-cookie
requirement: DISABLED
register: flow_v2_result
- name: Expose flow_v2_result to parent scope
ansible.builtin.set_fact:
flow_v2_result: "{{ flow_v2_result }}"
no_log: true

View file

@ -0,0 +1,144 @@
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
- name: Retrieve access token
ansible.builtin.include_tasks:
file: ../actions/fetch_access_token.yml
- name: Fetch all authentication flows
ansible.builtin.uri:
url: "{{ url }}/admin/realms/{{ realm }}/authentication/flows"
method: GET
headers:
Accept: application/json
User-agent: Ansible
Authorization: "Bearer {{ access_token }}"
return_content: true
register: keycloak_flows_response
no_log: true
- name: Extract flow id for alias 'Integration Test Flow'
ansible.builtin.set_fact:
test_flow_id: >-
{{ keycloak_flows_response.json
| selectattr('alias', 'equalto', 'Integration Test Flow')
| map(attribute='id')
| first }}
no_log: true
- name: Fetch basic flow data for 'Integration Test Flow'
ansible.builtin.uri:
url: "{{ url }}/admin/realms/{{ realm }}/authentication/flows/{{ test_flow_id }}"
method: GET
headers:
Accept: application/json
User-agent: Ansible
Authorization: "Bearer {{ access_token }}"
return_content: true
register: test_flow_top_level_data
no_log: true
- name: Assert flow attributes
ansible.builtin.assert:
that:
- test_flow_top_level_data.json.alias == "Integration Test Flow"
- test_flow_top_level_data.json.providerId == "basic-flow"
- test_flow_top_level_data.json.topLevel == true
- test_flow_top_level_data.json.builtIn == false
- name: Fetch flow executions for 'Integration Test Flow'
ansible.builtin.uri:
url: "{{ url }}/admin/realms/{{ realm }}/authentication/flows/Integration%20Test%20Flow/executions"
method: GET
headers:
Accept: application/json
User-agent: Ansible
Authorization: "Bearer {{ access_token }}"
return_content: true
register: test_flow_executions
no_log: true
- name: Assert flow executions
ansible.builtin.assert:
that:
- test_flow_executions.json | length == 6
- test_flow_executions.json[0].providerId == "idp-review-profile"
- test_flow_executions.json[0].requirement == "REQUIRED"
- test_flow_executions.json[0].index == 0
- test_flow_executions.json[0].priority == 0
- test_flow_executions.json[0].level == 0
- test_flow_executions.json[0].authenticationConfig is not none
- test_flow_executions.json[0]['authenticationFlow'] is not defined or test_flow_executions.json[0].authenticationFlow == false
- test_flow_executions.json[1].displayName == "Integration Test Flow - User creation or linking"
- test_flow_executions.json[1].requirement == "REQUIRED"
- test_flow_executions.json[1].index == 1
- test_flow_executions.json[1].priority == 1
- test_flow_executions.json[1].level == 0
- test_flow_executions.json[1]['authenticationConfig'] is not defined
- test_flow_executions.json[1].authenticationFlow == true
- test_flow_executions.json[2].providerId == "idp-create-user-if-unique"
- test_flow_executions.json[2].requirement == "ALTERNATIVE"
- test_flow_executions.json[2].index == 0
- test_flow_executions.json[2].priority == 0
- test_flow_executions.json[2].level == 1
- test_flow_executions.json[2].authenticationConfig is not none
- test_flow_executions.json[2]['authenticationFlow'] is not defined or test_flow_executions.json[0].authenticationFlow == false
- test_flow_executions.json[3].displayName == "Integration Test Flow - Handle Existing Account"
- test_flow_executions.json[3].requirement == "ALTERNATIVE"
- test_flow_executions.json[3].index == 1
- test_flow_executions.json[3].priority == 1
- test_flow_executions.json[3].level == 1
- test_flow_executions.json[3]['authenticationConfig'] is not defined
- test_flow_executions.json[3].authenticationFlow == true
- test_flow_executions.json[4].providerId == "idp-confirm-link"
- test_flow_executions.json[4].requirement == "REQUIRED"
- test_flow_executions.json[4].index == 0
- test_flow_executions.json[4].priority == 0
- test_flow_executions.json[4].level == 2
- test_flow_executions.json[4]['authenticationConfig'] is not defined
- test_flow_executions.json[4]['authenticationFlow'] is not defined or test_flow_executions.json[0].authenticationFlow == false
- test_flow_executions.json[5].providerId == "auth-cookie"
- test_flow_executions.json[5].requirement == "REQUIRED"
- test_flow_executions.json[5].index == 2
- test_flow_executions.json[5].priority == 2
- test_flow_executions.json[5].level == 0
- test_flow_executions.json[5]['authenticationConfig'] is not defined
- test_flow_executions.json[5]['authenticationFlow'] is not defined or test_flow_executions.json[0].authenticationFlow == false
- name: Fetch flow execution config for 'idp-review-profile'
ansible.builtin.uri:
url: "{{ url }}/admin/realms/{{ realm }}/authentication/config/{{ test_flow_executions.json[0].authenticationConfig }}"
method: GET
headers:
Accept: application/json
User-agent: Ansible
Authorization: "Bearer {{ access_token }}"
return_content: true
register: test_flow_execution_idp_review_profile_config
no_log: true
- name: Assert flow execution config for 'idp-review-profile'
ansible.builtin.assert:
that:
- test_flow_execution_idp_review_profile_config.json.alias == "Integration Test Flow - review profile config"
- test_flow_execution_idp_review_profile_config.json.config is not none
- test_flow_execution_idp_review_profile_config.json.config['update.profile.on.first.login'] == "missing"
- name: Fetch flow execution config for 'idp-create-user-if-unique'
ansible.builtin.uri:
url: "{{ url }}/admin/realms/{{ realm }}/authentication/config/{{ test_flow_executions.json[2].authenticationConfig }}"
method: GET
headers:
Accept: application/json
User-agent: Ansible
Authorization: "Bearer {{ access_token }}"
return_content: true
register: test_flow_execution_idp_create_user_if_unique
no_log: true
- name: Assert flow execution config for 'idp-create-user-if-unique'
ansible.builtin.assert:
that:
- test_flow_execution_idp_create_user_if_unique.json.alias == "Integration Test Flow - create unique user config"
- test_flow_execution_idp_create_user_if_unique.json.config is not none
- test_flow_execution_idp_create_user_if_unique.json.config['require.password.update.after.registration'] == "false"

View file

@ -0,0 +1,151 @@
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
- name: Retrieve access token
ansible.builtin.include_tasks:
file: ../actions/fetch_access_token.yml
- name: Fetch all authentication flows
ansible.builtin.uri:
url: "{{ url }}/admin/realms/{{ realm }}/authentication/flows"
method: GET
headers:
Accept: application/json
User-agent: Ansible
Authorization: "Bearer {{ access_token }}"
return_content: true
register: keycloak_flows_response
no_log: true
- name: Extract flow id for alias 'Integration Test Flow'
ansible.builtin.set_fact:
test_flow_id: >-
{{ keycloak_flows_response.json
| selectattr('alias', 'equalto', 'Integration Test Flow')
| map(attribute='id')
| first }}
no_log: true
- name: Fetch basic flow data for 'Integration Test Flow'
ansible.builtin.uri:
url: "{{ url }}/admin/realms/{{ realm }}/authentication/flows/{{ test_flow_id }}"
method: GET
headers:
Accept: application/json
User-agent: Ansible
Authorization: "Bearer {{ access_token }}"
return_content: true
register: test_flow_top_level_data
no_log: true
- name: Assert flow attributes
ansible.builtin.assert:
that:
- test_flow_top_level_data.json.alias == "Integration Test Flow"
- test_flow_top_level_data.json.providerId == "basic-flow"
- test_flow_top_level_data.json.topLevel == true
- test_flow_top_level_data.json.builtIn == false
- name: Fetch flow executions for 'Integration Test Flow'
ansible.builtin.uri:
url: "{{ url }}/admin/realms/{{ realm }}/authentication/flows/Integration%20Test%20Flow/executions"
method: GET
headers:
Accept: application/json
User-agent: Ansible
Authorization: "Bearer {{ access_token }}"
return_content: true
register: test_flow_executions
no_log: true
- name: Assert flow executions
ansible.builtin.assert:
that:
- test_flow_executions.json | length == 7
- test_flow_executions.json[0].providerId == "idp-review-profile"
- test_flow_executions.json[0].requirement == "REQUIRED"
- test_flow_executions.json[0].index == 0
- test_flow_executions.json[0].priority == 0
- test_flow_executions.json[0].level == 0
- test_flow_executions.json[0].authenticationConfig is not none
- test_flow_executions.json[0]['authenticationFlow'] is not defined or test_flow_executions.json[0].authenticationFlow == false
- test_flow_executions.json[1].displayName == "Integration Test Flow - User creation or linking"
- test_flow_executions.json[1].requirement == "REQUIRED"
- test_flow_executions.json[1].index == 1
- test_flow_executions.json[1].priority == 1
- test_flow_executions.json[1].level == 0
- test_flow_executions.json[1]['authenticationConfig'] is not defined
- test_flow_executions.json[1].authenticationFlow == true
- test_flow_executions.json[2].providerId == "idp-create-user-if-unique"
- test_flow_executions.json[2].requirement == "ALTERNATIVE"
- test_flow_executions.json[2].index == 0
- test_flow_executions.json[2].priority == 0
- test_flow_executions.json[2].level == 1
- test_flow_executions.json[2].authenticationConfig is not none
- test_flow_executions.json[2]['authenticationFlow'] is not defined or test_flow_executions.json[0].authenticationFlow == false
- test_flow_executions.json[3].providerId == "auth-cookie"
- test_flow_executions.json[3].requirement == "REQUIRED"
- test_flow_executions.json[3].index == 1
- test_flow_executions.json[3].priority == 1
- test_flow_executions.json[3].level == 1
- test_flow_executions.json[3]['authenticationConfig'] is not defined
- test_flow_executions.json[3]['authenticationFlow'] is not defined or test_flow_executions.json[0].authenticationFlow == false
- test_flow_executions.json[4].displayName == "Integration Test Flow - Handle Existing Account"
- test_flow_executions.json[4].requirement == "ALTERNATIVE"
- test_flow_executions.json[4].index == 2
- test_flow_executions.json[4].priority == 2
- test_flow_executions.json[4].level == 1
- test_flow_executions.json[4]['authenticationConfig'] is not defined
- test_flow_executions.json[4].authenticationFlow == true
- test_flow_executions.json[5].providerId == "idp-confirm-link"
- test_flow_executions.json[5].requirement == "REQUIRED"
- test_flow_executions.json[5].index == 0
- test_flow_executions.json[5].priority == 0
- test_flow_executions.json[5].level == 2
- test_flow_executions.json[5]['authenticationConfig'] is not defined
- test_flow_executions.json[5]['authenticationFlow'] is not defined or test_flow_executions.json[0].authenticationFlow == false
- test_flow_executions.json[6].providerId == "auth-cookie"
- test_flow_executions.json[6].requirement == "DISABLED"
- test_flow_executions.json[6].index == 2
- test_flow_executions.json[6].priority == 2
- test_flow_executions.json[6].level == 0
- test_flow_executions.json[6]['authenticationConfig'] is not defined
- test_flow_executions.json[6]['authenticationFlow'] is not defined or test_flow_executions.json[0].authenticationFlow == false
- name: Fetch flow execution config for 'idp-review-profile'
ansible.builtin.uri:
url: "{{ url }}/admin/realms/{{ realm }}/authentication/config/{{ test_flow_executions.json[0].authenticationConfig }}"
method: GET
headers:
Accept: application/json
User-agent: Ansible
Authorization: "Bearer {{ access_token }}"
return_content: true
register: test_flow_execution_idp_review_profile_config
no_log: true
- name: Assert flow execution config for 'idp-review-profile'
ansible.builtin.assert:
that:
- test_flow_execution_idp_review_profile_config.json.alias == "Integration Test Flow - review profile config"
- test_flow_execution_idp_review_profile_config.json.config is not none
- test_flow_execution_idp_review_profile_config.json.config['update.profile.on.first.login'] == "missing"
- name: Fetch flow execution config for 'idp-create-user-if-unique'
ansible.builtin.uri:
url: "{{ url }}/admin/realms/{{ realm }}/authentication/config/{{ test_flow_executions.json[2].authenticationConfig }}"
method: GET
headers:
Accept: application/json
User-agent: Ansible
Authorization: "Bearer {{ access_token }}"
return_content: true
register: test_flow_execution_idp_create_user_if_unique
no_log: true
- name: Assert flow execution config for 'idp-create-user-if-unique'
ansible.builtin.assert:
that:
- test_flow_execution_idp_create_user_if_unique.json.alias == "Integration Test Flow - create unique user config"
- test_flow_execution_idp_create_user_if_unique.json.config is not none
- test_flow_execution_idp_create_user_if_unique.json.config['require.password.update.after.registration'] == "true"

View file

@ -0,0 +1,26 @@
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
- name: Install required packages
pip:
name:
- jmespath
- requests
register: result
until: result is success
- name: Executing Flow Creation tests
ansible.builtin.include_tasks:
file: tests/test_flow_creation.yml
- name: Executing unused Flow Modification tests
ansible.builtin.include_tasks:
file: tests/test_unused_flow_modification.yml
- name: Executing used Flow Modification tests
ansible.builtin.include_tasks:
file: tests/test_used_flow_modification.yml
- name: Executing Flow Deletion tests
ansible.builtin.include_tasks:
file: tests/test_flow_deletion.yml

View file

@ -0,0 +1,33 @@
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
- name: Setup Test
ansible.builtin.include_tasks:
file: test_setup.yml
- name: Create the new flow <Integration Test Flow>
ansible.builtin.include_tasks:
file: ../actions/flow_v1.yml
- name: Assert the flow creation result
ansible.builtin.assert:
that:
- flow_v1_result is changed
- flow_v1_result.diff is defined
msg: "Expected changes and a diff but got: changed={{ flow_v1_result.changed }}, diff={{ flow_v1_result.get('diff') }}"
- name: Assert the created flow <Integration Test Flow>
ansible.builtin.include_tasks:
file: ../assertions/assertion_flow_v1.yml
# Check idempotency, by trying to create the existing flow again
- name: Trying to create the <Integration Test Flow> again, although nothing changed
ansible.builtin.include_tasks:
file: ../actions/flow_v1.yml
- name: Assert that the task didn't re-create the flow, because the flow didn't change
ansible.builtin.assert:
that:
- flow_v1_result is not changed
- flow_v1_result.diff is not defined
msg: "Expected no changes and no diff but got: changed={{ flow_v1_result.changed }}, diff={{ flow_v1_result.get('diff') }}"

View file

@ -0,0 +1,44 @@
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
- name: Setup Test
ansible.builtin.include_tasks:
file: test_setup.yml
- name: Create the new flow <Integration Test Flow>
ansible.builtin.include_tasks:
file: ../actions/flow_v1.yml
- name: Delete the flow <Integration Test Flow>
community.general.keycloak_authentication_v2:
auth_keycloak_url: "{{ url }}"
auth_realm: "{{ admin_realm }}"
auth_username: "{{ admin_user }}"
auth_password: "{{ admin_password }}"
realm: "{{ realm }}"
alias: Integration Test Flow
state: absent
register: flow_deletion_result
- name: Assert that the flow deletion result
ansible.builtin.assert:
that:
- flow_deletion_result is changed
- flow_deletion_result.diff is defined
msg: "Expected changes and a diff but got: changed={{ flow_deletion_result.changed }}, diff={{ flow_deletion_result.get('diff') }}"
- name: Retrieve access token
ansible.builtin.include_tasks:
file: ../actions/fetch_access_token.yml
- name: Assert that the flow does not exist anymore
ansible.builtin.uri:
url: "{{ url }}/admin/realms/{{ realm }}/authentication/flows/Integratoin%20Test%20Flow/executions"
method: GET
headers:
Accept: application/json
User-agent: Ansible
Authorization: "Bearer {{ access_token }}"
return_content: true
status_code: 404
register: flow_response

View file

@ -0,0 +1,46 @@
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
- name: Start container
community.docker.docker_container:
name: mykeycloak
image: "quay.io/keycloak/keycloak:{{ keycloak_version }}"
command: start-dev
env:
KC_HTTP_RELATIVE_PATH: /auth
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: password
ports:
- "{{ keycloak_port }}:8080"
detach: true
auto_remove: true
memory: 2200M
- name: Wait for Keycloak
uri:
url: "{{ url }}/admin/"
status_code: 200
validate_certs: false
register: result
until: result.status == 200
retries: 10
delay: 10
- name: Delete realm if exists
community.general.keycloak_realm:
auth_keycloak_url: "{{ url }}"
auth_realm: "{{ admin_realm }}"
auth_username: "{{ admin_user }}"
auth_password: "{{ admin_password }}"
realm: "{{ realm }}"
state: absent
- name: Create realm
community.general.keycloak_realm:
auth_keycloak_url: "{{ url }}"
auth_realm: "{{ admin_realm }}"
auth_username: "{{ admin_user }}"
auth_password: "{{ admin_password }}"
id: "{{ realm }}"
realm: "{{ realm }}"
state: present

View file

@ -0,0 +1,41 @@
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
- name: Setup Test
ansible.builtin.include_tasks:
file: test_setup.yml
- name: Create the new flow <Integration Test Flow>
ansible.builtin.include_tasks:
file: ../actions/flow_v1.yml
- name: Modify the flow <Integration Test Flow>'
ansible.builtin.include_tasks:
file: ../actions/flow_v2.yml
- name: Assert the flow creation modification result
ansible.builtin.assert:
that:
- flow_v2_result is changed
- flow_v2_result.diff is defined
msg: "Expected changes and a diff but got: changed={{ flow_v2_result.changed }}, diff={{ flow_v2_result.get('diff') }}"
- name: Assert the modified flow <Integration Test Flow>
ansible.builtin.include_tasks:
file: ../assertions/assertion_flow_v2.yml
# Revert the modifications from the previous step
- name: Revert the modifications the flow <Integration Test Flow>
ansible.builtin.include_tasks:
file: ../actions/flow_v1.yml
- name: Assert the flow modification result
ansible.builtin.assert:
that:
- flow_v1_result is changed
- flow_v1_result.diff is defined
msg: "Expected changes and a diff but got: changed={{ flow_v1_result.changed }}, diff={{ flow_v1_result.get('diff') }}"
- name: Assert the flow <Integration Test Flow> after reverting the modifications
ansible.builtin.include_tasks:
file: ../assertions/assertion_flow_v1.yml

View file

@ -0,0 +1,111 @@
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
- name: Setup Test
ansible.builtin.include_tasks:
file: test_setup.yml
- name: Create the new flow <Integration Test Flow>
ansible.builtin.include_tasks:
file: ../actions/flow_v1.yml
- name: Assign the flow <Integration Test Flow> as default browser flow
community.general.keycloak_realm:
auth_keycloak_url: "{{ url }}"
auth_realm: "{{ admin_realm }}"
auth_username: "{{ admin_user }}"
auth_password: "{{ admin_password }}"
id: "{{ realm }}"
realm: "{{ realm }}"
state: present
browser_flow: Integration Test Flow
- name: Modify the flow <Integration Test Flow> although it is bound as realm browser flow
ansible.builtin.include_tasks:
file: ../actions/flow_v2.yml
- name: Assert the flow modification result
ansible.builtin.assert:
that:
- flow_v2_result is changed
- flow_v2_result.diff is defined
msg: "Expected changes and a diff but got: changed={{ flow_v2_result.changed }}, diff={{ flow_v2_result.get('diff') }}"
- name: Assert the flow <Integration Test Flow> after the modifications
ansible.builtin.include_tasks:
file: ../assertions/assertion_flow_v2.yml
- name: Fetch realm data to validate if the browser flow is still set to <Integration Test Flow>
community.general.keycloak_realm:
auth_keycloak_url: "{{ url }}"
auth_realm: "{{ admin_realm }}"
auth_username: "{{ admin_user }}"
auth_password: "{{ admin_password }}"
id: "{{ realm }}"
realm: "{{ realm }}"
state: present
register: realm_result
- name: Assert realm browser flow binding
ansible.builtin.assert:
that:
- realm_result.end_state.browserFlow == "Integration Test Flow"
- name: Create a client with browser override <Integration Test Flow>
community.general.keycloak_client:
auth_keycloak_url: "{{ url }}"
auth_realm: "{{ admin_realm }}"
auth_username: "{{ admin_user }}"
auth_password: "{{ admin_password }}"
realm: "{{ realm }}"
client_id: "test_client"
state: present
authentication_flow_binding_overrides:
browser_name: "Integration Test Flow"
- name: Revert the flow modifications of <Integration Test Flow> although it is bound as realm browser and client override flow
ansible.builtin.include_tasks:
file: ../actions/flow_v1.yml
- name: Assert the flow modification result
ansible.builtin.assert:
that:
- flow_v1_result is changed
- flow_v1_result.diff is defined
msg: "Expected changes and a diff but got: changed={{ flow_v1_result.changed }}, diff={{ flow_v1_result.get('diff') }}"
- name: Assert the flow <Integration Test Flow> after the revert
ansible.builtin.include_tasks:
file: ../assertions/assertion_flow_v1.yml
- name: Fetch client data
community.general.keycloak_client:
auth_keycloak_url: "{{ url }}"
auth_realm: "{{ admin_realm }}"
auth_username: "{{ admin_user }}"
auth_password: "{{ admin_password }}"
realm: "{{ realm }}"
client_id: "test_client"
state: present
register: client_result
- name: Retrieve access token
ansible.builtin.include_tasks:
file: ../actions/fetch_access_token.yml
- name: Fetch authentication flow
ansible.builtin.uri:
url: "{{ url }}/admin/realms/{{ realm }}/authentication/flows/{{ client_result.end_state.authenticationFlowBindingOverrides.browser }}"
method: GET
headers:
Accept: application/json
User-agent: Ansible
Authorization: "Bearer {{ access_token }}"
return_content: true
register: flow_response
- name: Assert client flow override binding
ansible.builtin.assert:
that:
- flow_response.json is defined
- flow_response.json.alias == "Integration Test Flow"

View file

@ -0,0 +1,14 @@
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
keycloak_version: latest
keycloak_port: 8080
url: "http://localhost:{{ keycloak_port }}/auth"
admin_realm: master
admin_user: admin
admin_password: password
realm: myrealm
keycloak_no_otp_required_pattern_orinale: "X-Forwarded-For: 10\\.[0-9\\.:]+"
keycloak_no_otp_required_pattern_modifed: "X-Original-Forwarded-For: 10\\.[0-9\\.:]+"