Skip to content

Commit cc5cf98

Browse files
Fix: grant revoked priv (#434)
* Fix: exclude mysql 8 from test_mysql_user's 'Assert that priv did not change' test * Add tests to verify that GRANT permission is present after user modification * Fix: do not revoke GRANT permission when it's already allowed and present in priv parameter * Deduplicate tests name Easier to debug this way * Fix assertions named 'GRANT permission is present' * Only revoke grant option if it exists and absence is requested * Fix assertion comments * Fix: Only revoke grant option if it exists and absence is requested * Avoid pointless revocations when ALL are granted * Assert that priv did not change on mariadb also * Fix: sanity and unity tests * Format long lines * Add changelog fragment Co-authored-by: Laurent Indermühle <laurent.indermuehle@pm.me>
1 parent aef6a20 commit cc5cf98

File tree

3 files changed

+83
-4
lines changed

3 files changed

+83
-4
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
bugfixes:
3+
- mysql_user - grant option was revoked accidentally when modifying users.
4+
This fix revokes grant option only when privs are setup to do that
5+
(https://github.com/ansible-collections/community.mysql/issues/77#issuecomment-1209693807).

plugins/module_utils/user.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,9 +359,20 @@ def user_mod(cursor, user, host, host_all, password, encrypted,
359359
revoke_privs = list(set(new_priv[db_table]) & set(curr_priv[db_table]))
360360
else:
361361
# When replacing (neither append_privs nor subtract_privs), grant all missing privileges
362-
# and revoke existing privileges that were not requested.
362+
# and revoke existing privileges that were not requested...
363363
grant_privs = list(set(new_priv[db_table]) - set(curr_priv[db_table]))
364364
revoke_privs = list(set(curr_priv[db_table]) - set(new_priv[db_table]))
365+
366+
# ... avoiding pointless revocations when ALL are granted
367+
if 'ALL' in grant_privs or 'ALL PRIVILEGES' in grant_privs:
368+
revoke_privs = list(set(['GRANT', 'PROXY']).intersection(set(revoke_privs)))
369+
370+
# Only revoke grant option if it exists and absence is requested
371+
#
372+
# For more details
373+
# https://github.com/ansible-collections/community.mysql/issues/77#issuecomment-1209693807
374+
grant_option = 'GRANT' in revoke_privs and 'GRANT' not in grant_privs
375+
365376
if grant_privs == ['GRANT']:
366377
# USAGE grants no privileges, it is only needed because 'WITH GRANT OPTION' cannot stand alone
367378
grant_privs.append('USAGE')

tests/integration/targets/test_mysql_user/tasks/test_privs.yml

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@
164164
that:
165165
- result is changed
166166

167-
- name: Test idempotency (expect ok)
167+
- name: Test idempotency with a long privileges list (expect ok)
168168
mysql_user:
169169
<<: *mysql_params
170170
name: '{{ user_name_2 }}'
@@ -173,12 +173,75 @@
173173
state: present
174174
register: result
175175

176-
# FIXME: on mariadb >=10.5.2 there's always a change because the REPLICATION CLIENT privilege was renamed to BINLOG MONITOR
176+
# FIXME: on mysql >=8 and mariadb >=10.5.2 there's always a change because
177+
# the REPLICATION CLIENT privilege was renamed to BINLOG MONITOR
178+
- name: Assert that priv did not change
179+
assert:
180+
that:
181+
- result is not changed
182+
when: (install_type == 'mysql' and mysql_version is version('8', '<')) or
183+
(install_type == 'mariadb' and mariadb_version is version('10.5', '<'))
184+
185+
- name: remove username
186+
mysql_user:
187+
<<: *mysql_params
188+
name: '{{ user_name_2 }}'
189+
password: '{{ user_password_2 }}'
190+
state: absent
191+
192+
# ============================================================
193+
- name: grant all privileges with grant option
194+
mysql_user:
195+
<<: *mysql_params
196+
name: '{{ user_name_2 }}'
197+
password: '{{ user_password_2 }}'
198+
priv: '*.*:ALL,GRANT'
199+
state: present
200+
register: result
201+
202+
- name: Assert that priv changed
203+
assert:
204+
that:
205+
- result is changed
206+
207+
- name: Collect user info by host
208+
community.mysql.mysql_info:
209+
<<: *mysql_params
210+
filter: "users"
211+
register: mysql_info_about_users
212+
213+
- name: Assert that 'GRANT' permission is present
214+
assert:
215+
that:
216+
- mysql_info_about_users.users.localhost.{{ user_name_2 }}.Grant_priv == 'Y'
217+
218+
- name: Test idempotency (expect ok)
219+
mysql_user:
220+
<<: *mysql_params
221+
name: '{{ user_name_2 }}'
222+
password: '{{ user_password_2 }}'
223+
priv: '*.*:ALL,GRANT'
224+
state: present
225+
register: result
226+
227+
# FIXME: on mysql >=8 there's always a change (ALL PRIVILEGES -> specific privileges)
177228
- name: Assert that priv did not change
178229
assert:
179230
that:
180231
- result is not changed
181-
when: install_type == 'mysql' or (install_type == 'mariadb' and mariadb_version is version('10.2', '=='))
232+
when: (install_type == 'mysql' and mysql_version is version('8', '<')) or
233+
(install_type == 'mariadb')
234+
235+
- name: Collect user info by host
236+
community.mysql.mysql_info:
237+
<<: *mysql_params
238+
filter: "users"
239+
register: mysql_info_about_users
240+
241+
- name: Assert that 'GRANT' permission is present
242+
assert:
243+
that:
244+
- mysql_info_about_users.users.localhost.{{ user_name_2 }}.Grant_priv == 'Y'
182245

183246
# ============================================================
184247
- name: update user with invalid privileges

0 commit comments

Comments
 (0)