From b34c23d07d1fd2097767a5e16e153cbf20ed8973 Mon Sep 17 00:00:00 2001 From: Markus Bergholz Date: Wed, 8 Feb 2023 09:24:35 +0100 Subject: [PATCH] Fix revoke only grant (#503) * fix * test * changelog --- .../fragments/503-fix-revoke-grant-only.yml | 2 + plugins/module_utils/user.py | 20 ++++--- .../targets/test_mysql_user/tasks/main.yml | 2 + .../tasks/revoke_only_grant.yml | 58 +++++++++++++++++++ 4 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 changelogs/fragments/503-fix-revoke-grant-only.yml create mode 100644 tests/integration/targets/test_mysql_user/tasks/revoke_only_grant.yml diff --git a/changelogs/fragments/503-fix-revoke-grant-only.yml b/changelogs/fragments/503-fix-revoke-grant-only.yml new file mode 100644 index 00000000..5de4d4b1 --- /dev/null +++ b/changelogs/fragments/503-fix-revoke-grant-only.yml @@ -0,0 +1,2 @@ +bugfixes: + - mysql_user - when revoke privs consists only of ``GRANT``, a 2nd revoke query is executed with empty privs to revoke that ended in an SQL exception (https://github.com/ansible-collections/community.mysql/pull/503). \ No newline at end of file diff --git a/plugins/module_utils/user.py b/plugins/module_utils/user.py index e36aa571..fc4c40e8 100644 --- a/plugins/module_utils/user.py +++ b/plugins/module_utils/user.py @@ -692,17 +692,19 @@ def privileges_revoke(cursor, user, host, db_table, priv, grant_option, maria_ro query = ' '.join(query) cursor.execute(query, (user, host)) priv_string = ",".join([p for p in priv if p not in ('GRANT', )]) - query = ["REVOKE %s ON %s" % (priv_string, db_table)] - if not maria_role: - query.append("FROM %s@%s") - params = (user, host) - else: - query.append("FROM %s") - params = (user,) + if priv_string != "": + query = ["REVOKE %s ON %s" % (priv_string, db_table)] - query = ' '.join(query) - cursor.execute(query, params) + if not maria_role: + query.append("FROM %s@%s") + params = (user, host) + else: + query.append("FROM %s") + params = (user,) + + query = ' '.join(query) + cursor.execute(query, params) cursor.execute("FLUSH PRIVILEGES") diff --git a/tests/integration/targets/test_mysql_user/tasks/main.yml b/tests/integration/targets/test_mysql_user/tasks/main.yml index d8293223..5a029b8b 100644 --- a/tests/integration/targets/test_mysql_user/tasks/main.yml +++ b/tests/integration/targets/test_mysql_user/tasks/main.yml @@ -322,3 +322,5 @@ # https://github.com/ansible-collections/community.mysql/issues/231 - include: test_user_grants_with_roles_applied.yml + + - include: revoke_only_grant.yml \ No newline at end of file diff --git a/tests/integration/targets/test_mysql_user/tasks/revoke_only_grant.yml b/tests/integration/targets/test_mysql_user/tasks/revoke_only_grant.yml new file mode 100644 index 00000000..19b9b6a9 --- /dev/null +++ b/tests/integration/targets/test_mysql_user/tasks/revoke_only_grant.yml @@ -0,0 +1,58 @@ +--- +- vars: + mysql_parameters: &mysql_params + login_user: '{{ mysql_user }}' + login_password: '{{ mysql_password }}' + login_host: 127.0.0.1 + login_port: '{{ mysql_primary_port }}' + block: + - name: Drop mysql user if exists + mysql_user: + <<: *mysql_params + name: '{{ user_name_1 }}' + state: absent + ignore_errors: true + + - name: create user with two grants + mysql_user: + <<: *mysql_params + name: "{{ user_name_1 }}" + password: "{{ user_password_1 }}" + update_password: on_create + priv: '*.*:SELECT,GRANT' + + - name: user must have only on priv, grant priv must be dropped + register: result + mysql_user: + <<: *mysql_params + name: "{{ user_name_1 }}" + password: "{{ user_password_1 }}" + update_password: on_create + priv: '*.*:SELECT' + + - assert: + that: + - result is not failed + - result is changed + + - name: immutable - user must have only on priv, grant priv must be dropped + register: result + mysql_user: + <<: *mysql_params + name: "{{ user_name_1 }}" + password: "{{ user_password_1 }}" + update_password: on_create + priv: '*.*:SELECT' + + - assert: + that: + - result is not failed + - result is not changed + + always: + - name: drop user + mysql_user: + <<: *mysql_params + name: '{{ user_name_1 }}' + state: absent + ignore_errors: true