From 4381ac1bf379aa9bb4c80016de45c5dbba55ad1d Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 21:23:36 +0200 Subject: [PATCH] [PR #7126/721108d9 backport][stable-7] Add keycloak_authz_custom_policy module (#7290) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add keycloak_authz_custom_policy module (#7126) * Add keycloak_authz_custom_policy module * keycloak.py: add linefeed to keep linter happy * keycloak_authz_custom_policy: add basic integration tests * keycloak_authz_custom_policy: add support for check_mode * keycloak_authz_custom_policy: add check_mode-specific integration tests Signed-off-by: Samuli Seppänen * keycloak_authz_custom_policy: improve logging Signed-off-by: Samuli Seppänen * keycloak_authz_custom_policy: fix typo * keycloak_authz_custom_policy: add licensing information This should make this module REUSE compliant * keycloak_authz_custom_policy: remove comment markers from license files * keycloak_authz_custom_policy: fix typo in the example * keycloak_authz_custom_policy: fix typos in metadata * keycloak_authz_custom_policy: change version_added to 7.5.0 * Update plugins/modules/keycloak_authz_custom_policy.py Co-authored-by: Felix Fontein --------- Signed-off-by: Samuli Seppänen Co-authored-by: Felix Fontein (cherry picked from commit 721108d92eddd55721d586f78930e5fcab9131eb) Co-authored-by: Samuli Seppänen --- .github/BOTMETA.yml | 2 + .../identity/keycloak/keycloak.py | 24 ++ .../modules/keycloak_authz_custom_policy.py | 211 ++++++++++++++++++ .../keycloak_authz_custom_policy/aliases | 5 + .../policy/Containerfile | 4 + .../policy/Containerfile.license | 3 + .../policy/META-INF/keycloak-scripts.json | 14 ++ .../META-INF/keycloak-scripts.json.license | 3 + .../policy/build-policy.sh | 2 + .../policy/build-policy.sh.license | 3 + .../policy/policy-1.js | 1 + .../policy/policy-1.js.license | 3 + .../policy/policy-2.js | 1 + .../policy/policy-2.js.license | 3 + .../keycloak_authz_custom_policy/readme.adoc | 27 +++ .../tasks/main.yml | 168 ++++++++++++++ .../vars/main.yml | 11 + 17 files changed, 485 insertions(+) create mode 100644 plugins/modules/keycloak_authz_custom_policy.py create mode 100644 tests/integration/targets/keycloak_authz_custom_policy/aliases create mode 100644 tests/integration/targets/keycloak_authz_custom_policy/policy/Containerfile create mode 100644 tests/integration/targets/keycloak_authz_custom_policy/policy/Containerfile.license create mode 100644 tests/integration/targets/keycloak_authz_custom_policy/policy/META-INF/keycloak-scripts.json create mode 100644 tests/integration/targets/keycloak_authz_custom_policy/policy/META-INF/keycloak-scripts.json.license create mode 100755 tests/integration/targets/keycloak_authz_custom_policy/policy/build-policy.sh create mode 100644 tests/integration/targets/keycloak_authz_custom_policy/policy/build-policy.sh.license create mode 100644 tests/integration/targets/keycloak_authz_custom_policy/policy/policy-1.js create mode 100644 tests/integration/targets/keycloak_authz_custom_policy/policy/policy-1.js.license create mode 100644 tests/integration/targets/keycloak_authz_custom_policy/policy/policy-2.js create mode 100644 tests/integration/targets/keycloak_authz_custom_policy/policy/policy-2.js.license create mode 100644 tests/integration/targets/keycloak_authz_custom_policy/readme.adoc create mode 100644 tests/integration/targets/keycloak_authz_custom_policy/tasks/main.yml create mode 100644 tests/integration/targets/keycloak_authz_custom_policy/vars/main.yml diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index 237fcad8d9..23b0bf1cc9 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -703,6 +703,8 @@ files: maintainers: mattock $modules/keycloak_authz_permission.py: maintainers: mattock + $modules/keycloak_authz_custom_policy.py: + maintainers: mattock $modules/keycloak_authz_permission_info.py: maintainers: mattock $modules/keycloak_client_rolemapping.py: diff --git a/plugins/module_utils/identity/keycloak/keycloak.py b/plugins/module_utils/identity/keycloak/keycloak.py index a8d0db14d9..924d2113cd 100644 --- a/plugins/module_utils/identity/keycloak/keycloak.py +++ b/plugins/module_utils/identity/keycloak/keycloak.py @@ -116,6 +116,9 @@ URL_AUTHZ_PERMISSIONS = "{url}/admin/realms/{realm}/clients/{client_id}/authz/re URL_AUTHZ_RESOURCES = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/resource" +URL_AUTHZ_CUSTOM_POLICY = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/policy/{policy_type}" +URL_AUTHZ_CUSTOM_POLICIES = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/policy" + def keycloak_argument_spec(): """ @@ -2922,6 +2925,27 @@ class KeycloakAPI(object): list_of_groups.append(group_dict) return list_of_groups + def create_authz_custom_policy(self, policy_type, payload, client_id, realm): + """Create a custom policy for a Keycloak client""" + url = URL_AUTHZ_CUSTOM_POLICY.format(url=self.baseurl, policy_type=policy_type, client_id=client_id, realm=realm) + + try: + return open_url(url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(payload), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not create permission %s for client %s in realm %s: %s' % (payload['name'], client_id, realm, str(e))) + + def remove_authz_custom_policy(self, policy_id, client_id, realm): + """Remove a custom policy from a Keycloak client""" + url = URL_AUTHZ_CUSTOM_POLICIES.format(url=self.baseurl, client_id=client_id, realm=realm) + delete_url = "%s/%s" % (url, policy_id) + + try: + return open_url(delete_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not delete custom policy %s for client %s in realm %s: %s' % (id, client_id, realm, str(e))) + def get_authz_permission_by_name(self, name, client_id, realm): """Get authorization permission by name""" url = URL_AUTHZ_POLICIES.format(url=self.baseurl, client_id=client_id, realm=realm) diff --git a/plugins/modules/keycloak_authz_custom_policy.py b/plugins/modules/keycloak_authz_custom_policy.py new file mode 100644 index 0000000000..8363c252e2 --- /dev/null +++ b/plugins/modules/keycloak_authz_custom_policy.py @@ -0,0 +1,211 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2017, Eike Frost +# Copyright (c) 2021, Christophe Gilles +# 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 +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: keycloak_authz_custom_policy + +short_description: Allows administration of Keycloak client custom Javascript policies via Keycloak API + +version_added: 7.5.0 + +description: + - This module allows the administration of Keycloak client custom Javascript via the Keycloak REST + API. Custom Javascript policies are only available if a client has Authorization enabled and if + they have been deployed to the Keycloak server as JAR files. + + - This module requires access to the REST API via OpenID Connect; the user connecting and the realm + being used must have the requisite access rights. In a default Keycloak installation, admin-cli + and an admin user would work, as would a separate realm definition with the scope tailored + to your needs and a user having the expected roles. + + - The names of module options are snake_cased versions of the camelCase options used by Keycloak. + The Authorization Services paths and payloads have not officially been documented by the Keycloak project. + U(https://www.puppeteers.net/blog/keycloak-authorization-services-rest-api-paths-and-payload/) + +attributes: + check_mode: + support: full + diff_mode: + support: none + +options: + state: + description: + - State of the custom policy. + - On V(present), the custom policy will be created (or updated if it exists already). + - On V(absent), the custom policy will be removed if it exists. + choices: ['present', 'absent'] + default: 'present' + type: str + name: + description: + - Name of the custom policy to create. + type: str + required: true + policy_type: + description: + - The type of the policy. This must match the name of the custom policy deployed to the server. + - Multiple policies pointing to the same policy type can be created, but their names have to differ. + type: str + required: true + client_id: + description: + - The V(clientId) of the Keycloak client that should have the custom policy attached to it. + - This is usually a human-readable name of the Keycloak client. + type: str + required: true + realm: + description: + - The name of the Keycloak realm the Keycloak client is in. + type: str + required: true + +extends_documentation_fragment: + - community.general.keycloak + - community.general.attributes + +author: + - Samuli Seppänen (@mattock) +''' + +EXAMPLES = ''' +- name: Manage Keycloak custom authorization policy + community.general.keycloak_authz_custom_policy: + name: OnlyOwner + state: present + policy_type: script-policy.js + client_id: myclient + realm: myrealm + auth_keycloak_url: http://localhost:8080/auth + auth_username: keycloak + auth_password: keycloak + auth_realm: master +''' + +RETURN = ''' +msg: + description: Message as to what action was taken. + returned: always + type: str + +end_state: + description: Representation of the custom policy after module execution. + returned: on success + type: dict + contains: + name: + description: Name of the custom policy. + type: str + returned: when I(state=present) + sample: file:delete + policy_type: + description: Type of custom policy. + type: str + returned: when I(state=present) + sample: File delete + +''' + +from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak import KeycloakAPI, \ + keycloak_argument_spec, get_token, KeycloakError +from ansible.module_utils.basic import AnsibleModule + + +def main(): + """ + Module execution + + :return: + """ + argument_spec = keycloak_argument_spec() + + meta_args = dict( + state=dict(type='str', default='present', + choices=['present', 'absent']), + name=dict(type='str', required=True), + policy_type=dict(type='str', required=True), + client_id=dict(type='str', required=True), + realm=dict(type='str', required=True) + ) + + argument_spec.update(meta_args) + + module = AnsibleModule(argument_spec=argument_spec, + supports_check_mode=True, + required_one_of=( + [['token', 'auth_realm', 'auth_username', 'auth_password']]), + required_together=([['auth_realm', 'auth_username', 'auth_password']])) + + result = dict(changed=False, msg='', end_state={}) + + # Obtain access token, initialize API + try: + connection_header = get_token(module.params) + except KeycloakError as e: + module.fail_json(msg=str(e)) + + kc = KeycloakAPI(module, connection_header) + + # Convenience variables + state = module.params.get('state') + name = module.params.get('name') + policy_type = module.params.get('policy_type') + client_id = module.params.get('client_id') + realm = module.params.get('realm') + + cid = kc.get_client_id(client_id, realm=realm) + if not cid: + module.fail_json(msg='Invalid client %s for realm %s' % + (client_id, realm)) + + before_authz_custom_policy = kc.get_authz_policy_by_name( + name=name, client_id=cid, realm=realm) + + desired_authz_custom_policy = {} + desired_authz_custom_policy['name'] = name + desired_authz_custom_policy['type'] = policy_type + + # Modifying existing custom policies is not possible + if before_authz_custom_policy and state == 'present': + result['msg'] = "Custom policy %s already exists" % (name) + result['changed'] = False + result['end_state'] = desired_authz_custom_policy + elif not before_authz_custom_policy and state == 'present': + if module.check_mode: + result['msg'] = "Would create custom policy %s" % (name) + else: + kc.create_authz_custom_policy( + payload=desired_authz_custom_policy, policy_type=policy_type, client_id=cid, realm=realm) + result['msg'] = "Custom policy %s created" % (name) + + result['changed'] = True + result['end_state'] = desired_authz_custom_policy + elif before_authz_custom_policy and state == 'absent': + if module.check_mode: + result['msg'] = "Would remove custom policy %s" % (name) + else: + kc.remove_authz_custom_policy( + policy_id=before_authz_custom_policy['id'], client_id=cid, realm=realm) + result['msg'] = "Custom policy %s removed" % (name) + + result['changed'] = True + result['end_state'] = {} + elif not before_authz_custom_policy and state == 'absent': + result['msg'] = "Custom policy %s does not exist" % (name) + result['changed'] = False + result['end_state'] = {} + + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/tests/integration/targets/keycloak_authz_custom_policy/aliases b/tests/integration/targets/keycloak_authz_custom_policy/aliases new file mode 100644 index 0000000000..bd1f024441 --- /dev/null +++ b/tests/integration/targets/keycloak_authz_custom_policy/aliases @@ -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 diff --git a/tests/integration/targets/keycloak_authz_custom_policy/policy/Containerfile b/tests/integration/targets/keycloak_authz_custom_policy/policy/Containerfile new file mode 100644 index 0000000000..3303066dae --- /dev/null +++ b/tests/integration/targets/keycloak_authz_custom_policy/policy/Containerfile @@ -0,0 +1,4 @@ +FROM quay.io/keycloak/keycloak:20.0.2 + +COPY policy.jar /opt/keycloak/providers/ +RUN /opt/keycloak/bin/kc.sh build diff --git a/tests/integration/targets/keycloak_authz_custom_policy/policy/Containerfile.license b/tests/integration/targets/keycloak_authz_custom_policy/policy/Containerfile.license new file mode 100644 index 0000000000..a1390a69ed --- /dev/null +++ b/tests/integration/targets/keycloak_authz_custom_policy/policy/Containerfile.license @@ -0,0 +1,3 @@ +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 diff --git a/tests/integration/targets/keycloak_authz_custom_policy/policy/META-INF/keycloak-scripts.json b/tests/integration/targets/keycloak_authz_custom_policy/policy/META-INF/keycloak-scripts.json new file mode 100644 index 0000000000..9370c16cb6 --- /dev/null +++ b/tests/integration/targets/keycloak_authz_custom_policy/policy/META-INF/keycloak-scripts.json @@ -0,0 +1,14 @@ +{ + "policies": [ + { + "name": "MyPolicy1", + "fileName": "policy-1.js", + "description": "My Policy 1" + }, + { + "name": "MyPolicy2", + "fileName": "policy-2.js", + "description": "My Policy 2" + } + ] +} diff --git a/tests/integration/targets/keycloak_authz_custom_policy/policy/META-INF/keycloak-scripts.json.license b/tests/integration/targets/keycloak_authz_custom_policy/policy/META-INF/keycloak-scripts.json.license new file mode 100644 index 0000000000..a1390a69ed --- /dev/null +++ b/tests/integration/targets/keycloak_authz_custom_policy/policy/META-INF/keycloak-scripts.json.license @@ -0,0 +1,3 @@ +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 diff --git a/tests/integration/targets/keycloak_authz_custom_policy/policy/build-policy.sh b/tests/integration/targets/keycloak_authz_custom_policy/policy/build-policy.sh new file mode 100755 index 0000000000..eeca22f7e4 --- /dev/null +++ b/tests/integration/targets/keycloak_authz_custom_policy/policy/build-policy.sh @@ -0,0 +1,2 @@ +#!/bin/sh +zip -r policy.jar META-INF/keycloak-scripts.json policy-1.js policy-2.js diff --git a/tests/integration/targets/keycloak_authz_custom_policy/policy/build-policy.sh.license b/tests/integration/targets/keycloak_authz_custom_policy/policy/build-policy.sh.license new file mode 100644 index 0000000000..a1390a69ed --- /dev/null +++ b/tests/integration/targets/keycloak_authz_custom_policy/policy/build-policy.sh.license @@ -0,0 +1,3 @@ +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 diff --git a/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-1.js b/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-1.js new file mode 100644 index 0000000000..fa42b0719b --- /dev/null +++ b/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-1.js @@ -0,0 +1 @@ +$evaluation.grant(); diff --git a/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-1.js.license b/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-1.js.license new file mode 100644 index 0000000000..a1390a69ed --- /dev/null +++ b/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-1.js.license @@ -0,0 +1,3 @@ +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 diff --git a/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-2.js b/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-2.js new file mode 100644 index 0000000000..fa42b0719b --- /dev/null +++ b/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-2.js @@ -0,0 +1 @@ +$evaluation.grant(); diff --git a/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-2.js.license b/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-2.js.license new file mode 100644 index 0000000000..a1390a69ed --- /dev/null +++ b/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-2.js.license @@ -0,0 +1,3 @@ +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 diff --git a/tests/integration/targets/keycloak_authz_custom_policy/readme.adoc b/tests/integration/targets/keycloak_authz_custom_policy/readme.adoc new file mode 100644 index 0000000000..cc014158f9 --- /dev/null +++ b/tests/integration/targets/keycloak_authz_custom_policy/readme.adoc @@ -0,0 +1,27 @@ +// 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 + +To be able to run these integration tests a keycloak server must be +reachable under a specific url with a specific admin user and password. +The exact values expected for these parameters can be found in +'vars/main.yml' file. A vanilla Keycloak server will not be sufficient: +you will need to deploy a custom JAR file with two policies: + +* _MyPolicy1:_ policy-1.js +* _MyPolicy2:_ policy-2.js + +To create a customized Keycloak test instance running on Podman first +install the "zip" command, go to the policy subdirectory and then do + +[source,shell] +---- +./build-policy.sh +podman build --tag keycloak_authz_custom_policy_test:1.0.0 . +podman rm mykeycloak && podman run --name mykeycloak -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=password -e KC_HTTP_RELATIVE_PATH=/auth localhost/keycloak_authz_custom_policy_test:1.0.0 start-dev +---- + +This process probably also work with Docker just by replacing _podman_ with +_docker_. Modify the FROM argument in Containerfile to change Keycloak version +to test against. Quarkus versions of Keycloak should work - older versions +will not. diff --git a/tests/integration/targets/keycloak_authz_custom_policy/tasks/main.yml b/tests/integration/targets/keycloak_authz_custom_policy/tasks/main.yml new file mode 100644 index 0000000000..b22d751215 --- /dev/null +++ b/tests/integration/targets/keycloak_authz_custom_policy/tasks/main.yml @@ -0,0 +1,168 @@ +--- +# 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: Remove keycloak client to avoid failures from previous failed runs + community.general.keycloak_client: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + client_id: "{{ client_id }}" + state: absent + +- name: Create keycloak client with authorization services enabled + community.general.keycloak_client: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + client_id: "{{ client_id }}" + state: present + enabled: true + public_client: false + service_accounts_enabled: true + authorization_services_enabled: true + +- name: Create first custom policy (check_mode) + community.general.keycloak_authz_custom_policy: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + name: FirstCustomPolicy + state: present + policy_type: script-policy-1.js + realm: "{{ realm }}" + client_id: "{{ client_id }}" + check_mode: true + register: result + +- name: Assert that first custom policy was not created + assert: + that: + - result is changed + - result.end_state != {} + - result.end_state.name == "FirstCustomPolicy" + - result.end_state.type == "script-policy-1.js" + - result.msg == 'Would create custom policy FirstCustomPolicy' + +- name: Create first custom policy + community.general.keycloak_authz_custom_policy: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + name: FirstCustomPolicy + state: present + policy_type: script-policy-1.js + realm: "{{ realm }}" + client_id: "{{ client_id }}" + register: result + +- name: Assert that first custom policy was created + assert: + that: + - result is changed + - result.end_state != {} + - result.end_state.name == "FirstCustomPolicy" + - result.end_state.type == "script-policy-1.js" + - result.msg == 'Custom policy FirstCustomPolicy created' + +- name: Attempt to update first custom policy (not possible) + community.general.keycloak_authz_custom_policy: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + name: FirstCustomPolicy + state: present + policy_type: script-policy-2.js + realm: "{{ realm }}" + client_id: "{{ client_id }}" + register: result + +- name: Assert that first custom policy was not modified + assert: + that: + - result is not changed + - result.end_state != {} + - result.end_state.name == "FirstCustomPolicy" + - result.end_state.type == "script-policy-2.js" + - result.msg == 'Custom policy FirstCustomPolicy already exists' + +# Ensure that we can create multiple instances of the custom policy +- name: Create second instance of the custom policy + community.general.keycloak_authz_custom_policy: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + name: SecondCustomPolicy + state: present + policy_type: script-policy-1.js + realm: "{{ realm }}" + client_id: "{{ client_id }}" + register: result + +- name: Assert that second instance of the custom policy was created + assert: + that: + - result is changed + - result.end_state != {} + - result.end_state.name == "SecondCustomPolicy" + - result.end_state.type == "script-policy-1.js" + - result.msg == 'Custom policy SecondCustomPolicy created' + +- name: Remove second instance of the custom policy (check_mode) + community.general.keycloak_authz_custom_policy: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + name: SecondCustomPolicy + state: absent + policy_type: script-policy-1.js + realm: "{{ realm }}" + client_id: "{{ client_id }}" + check_mode: true + register: result + +- name: Assert that second custom policy was not removed + assert: + that: + - result is changed + - result.end_state == {} + - result.msg == 'Would remove custom policy SecondCustomPolicy' + +- name: Remove second instance of the custom policy + community.general.keycloak_authz_custom_policy: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + name: SecondCustomPolicy + state: absent + policy_type: script-policy-1.js + realm: "{{ realm }}" + client_id: "{{ client_id }}" + register: result + +- name: Assert that second custom policy was removed + assert: + that: + - result is changed + - result.end_state == {} + - result.msg == 'Custom policy SecondCustomPolicy removed' + +- name: Remove keycloak client + community.general.keycloak_client: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + client_id: "{{ client_id }}" + state: absent diff --git a/tests/integration/targets/keycloak_authz_custom_policy/vars/main.yml b/tests/integration/targets/keycloak_authz_custom_policy/vars/main.yml new file mode 100644 index 0000000000..c1d5fc9839 --- /dev/null +++ b/tests/integration/targets/keycloak_authz_custom_policy/vars/main.yml @@ -0,0 +1,11 @@ +--- +# 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 + +url: http://localhost:8080/auth +admin_realm: master +admin_user: admin +admin_password: password +realm: master +client_id: authz