
    Vh                     ^   d dl mZmZmZ eZdZdZdZd dl	Z	d dl
mZ d dlmZ d dlmZmZ d d	lmZmZmZmZmZmZmZmZ d d
lmZ ere ed      k  rd dlmZ nerd dlmZ  e d      Z!ddddddZ"d ddddZ#g Z$ G d de%      Zd Z& G d de'      Z( G d de'      Z)d Z*e+dk(  r e*        yy)     )absolute_importdivisionprint_functiona  
---
module: postgresql_privs
short_description: Grant or revoke privileges on PostgreSQL database objects
description:
- Grant or revoke privileges on PostgreSQL database objects.
- This module is basically a wrapper around most of the functionality of
  PostgreSQL's GRANT and REVOKE statements with detection of changes
  (GRANT/REVOKE I(privs) ON I(type) I(objs) TO/FROM I(roles)).
options:
  login_db:
    description:
    - Name of database to connect to.
    - The V(db) and V(database) aliases are deprecated and will be removed in version 5.0.0.
    required: true
    type: str
    aliases:
    - db
    - database
  state:
    description:
    - If C(present), the specified privileges are granted, if C(absent) they are revoked.
    type: str
    default: present
    choices: [ absent, present ]
  privs:
    description:
    - Comma separated list of privileges to grant/revoke.
    type: str
    aliases:
    - priv
  type:
    description:
    - Type of database object to set privileges on.
    - The C(default_privs) choice is available starting at version 2.7.
    - The C(foreign_data_wrapper) and C(foreign_server) object types are available since Ansible version 2.8.
    - The C(type) choice is available since Ansible version 2.10.
    - The C(procedure) is supported since collection version 1.3.0 and PostgreSQL 11.
    - The C(parameter) is supported since collection version 3.1.0 and PostgreSQL 15.
    - The C(table) is inclusive of foreign tables since collection version 3.6.0.
    type: str
    default: table
    choices: [ database, default_privs, foreign_data_wrapper, foreign_server, function,
               group, language, table, tablespace, schema, sequence, type, procedure, parameter ]
  objs:
    description:
    - Comma separated list of database objects to set privileges on.
    - If I(type) is C(table), C(partition table), C(sequence), C(function) or C(procedure),
      the special value C(ALL_IN_SCHEMA) can be provided instead to specify all
      database objects of I(type) in the schema specified via I(schema).
      (This also works with PostgreSQL < 9.0.) (C(ALL_IN_SCHEMA) is available
       for C(function) and C(partition table) since Ansible 2.8).
    - C(procedure) is supported since PostgreSQL 11 and community.postgresql collection 1.3.0.
    - C(parameter) is supported since PostgreSQL 15 and community.postgresql collection 3.1.0.
    - If I(type) is C(database), this parameter can be omitted, in which case
      privileges are set for the database specified via I(database).
    - If I(type) is C(function) or C(procedure), colons (":") in object names will be
      replaced with commas (needed to specify signatures, see examples).
    type: str
    aliases:
    - obj
  schema:
    description:
    - Schema that contains the database objects specified via I(objs).
    - May only be provided if I(type) is C(table), C(sequence), C(function), C(procedure), C(type),
      or C(default_privs). Defaults to C(public) in these cases.
    - Pay attention, for embedded types when I(type=type)
      I(schema) can be C(pg_catalog) or C(information_schema) respectively.
    - If not specified, uses C(public). Not to pass any schema, use C(not-specified).
    type: str
  roles:
    description:
    - Comma separated list of role (user/group) names to set permissions for.
    - Roles C(PUBLIC), C(CURRENT_ROLE), C(CURRENT_USER), C(SESSION_USER) are implicitly defined in PostgreSQL.
    - C(CURRENT_USER) and C(SESSION_USER) implicit roles are supported since collection version 3.1.0 and PostgreSQL 9.5.
    - C(CURRENT_ROLE) implicit role is supported since collection version 3.1.0 and PostgreSQL 14.
    type: str
    required: true
    aliases:
    - role
  fail_on_role:
    description:
    - If C(true), fail when target role (for whom privs need to be granted) does not exist.
      Otherwise just warn and continue.
    default: true
    type: bool
  session_role:
    description:
    - Switch to session_role after connecting.
    - The specified session_role must be a role that the current login_user is a member of.
    - Permissions checking for SQL commands is carried out as though the session_role were the one that had logged in originally.
    type: str
  target_roles:
    description:
    - A list of existing role (user/group) names to set as the
      default permissions for database objects subsequently created by them.
    - Parameter I(target_roles) is only available with C(type=default_privs).
    type: str
  grant_option:
    description:
    - Whether C(role) may grant/revoke the specified privileges/group memberships to others.
    - Set to C(false) to revoke GRANT OPTION, leave unspecified to make no changes.
    - I(grant_option) only has an effect if I(state) is C(present).
    type: bool
    aliases:
    - admin_option
  password:
    description:
    - The password to authenticate with.
    - This option has been B(deprecated) and will be removed in community.postgresql 4.0.0,
      use the I(login_password) option instead.
    - Mutually exclusive with I(login_password).
    type: str
    default: ''
  trust_input:
    description:
    - If C(false), check whether values of parameters I(roles), I(target_roles), I(session_role),
      I(schema) are potentially dangerous.
    - It makes sense to use C(false) only when SQL injections via the parameters are possible.
    type: bool
    default: true
    version_added: '0.2.0'

notes:
- Parameters that accept comma separated lists (I(privs), I(objs), I(roles))
  have singular alias names (I(priv), I(obj), I(role)).
- To revoke only C(GRANT OPTION) for a specific object, set I(state) to
  C(present) and I(grant_option) to C(false) (see examples).
- Note that when revoking privileges from a role R, this role  may still have
  access via privileges granted to any role R is a member of including C(PUBLIC).
- Note that when revoking privileges from a role R, you do so as the user
  specified via I(login_user). If R has been granted the same privileges by
  another user also, R can still access database objects via these privileges.
- When revoking privileges, C(RESTRICT) is assumed (see PostgreSQL docs).

seealso:
- module: community.postgresql.postgresql_user
- module: community.postgresql.postgresql_owner
- module: community.postgresql.postgresql_membership
- name: PostgreSQL privileges
  description: General information about PostgreSQL privileges.
  link: https://www.postgresql.org/docs/current/ddl-priv.html
- name: PostgreSQL GRANT command reference
  description: Complete reference of the PostgreSQL GRANT command documentation.
  link: https://www.postgresql.org/docs/current/sql-grant.html
- name: PostgreSQL REVOKE command reference
  description: Complete reference of the PostgreSQL REVOKE command documentation.
  link: https://www.postgresql.org/docs/current/sql-revoke.html

attributes:
  check_mode:
    support: full

extends_documentation_fragment:
- community.postgresql.postgres

author:
- Bernhard Weitzhofer (@b6d)
- Tobias Birkefeld (@tcraxs)
- Daniele Giudice (@RealGreenDragon)
a^  
# On database "library":
# GRANT SELECT, INSERT, UPDATE ON TABLE public.books, public.authors
# TO librarian, reader WITH GRANT OPTION
- name: Grant privs to librarian and reader on database library
  community.postgresql.postgresql_privs:
    login_db: library
    state: present
    privs: SELECT,INSERT,UPDATE
    type: table
    objs: books,authors
    schema: public
    roles: librarian,reader
    grant_option: true

- name: Same as above leveraging default values
  community.postgresql.postgresql_privs:
    login_db: library
    privs: SELECT,INSERT,UPDATE
    objs: books,authors
    roles: librarian,reader
    grant_option: true

# REVOKE GRANT OPTION FOR INSERT ON TABLE books FROM reader
# Note that role "reader" will be *granted* INSERT privilege itself if this
# isn't already the case (since state: present).
- name: Revoke privs from reader
  community.postgresql.postgresql_privs:
    login_db: library
    state: present
    priv: INSERT
    obj: books
    role: reader
    grant_option: false

# "public" is the default schema. This also works for PostgreSQL 8.x.
- name: REVOKE INSERT, UPDATE ON ALL TABLES IN SCHEMA public FROM reader
  community.postgresql.postgresql_privs:
    login_db: library
    state: absent
    privs: INSERT,UPDATE
    objs: ALL_IN_SCHEMA
    role: reader

- name: GRANT ALL PRIVILEGES ON SCHEMA public, math TO librarian
  community.postgresql.postgresql_privs:
    login_db: library
    privs: ALL
    type: schema
    objs: public,math
    role: librarian

# Note the separation of arguments with colons.
- name: GRANT ALL PRIVILEGES ON FUNCTION math.add(int, int) TO librarian, reader
  community.postgresql.postgresql_privs:
    login_db: library
    privs: ALL
    type: function
    obj: add(int:int)
    schema: math
    roles: librarian,reader

# Note that group role memberships apply cluster-wide and therefore are not
# restricted to database "library" here.
- name: GRANT librarian, reader TO alice, bob WITH ADMIN OPTION
  community.postgresql.postgresql_privs:
    login_db: library
    type: group
    objs: librarian,reader
    roles: alice,bob
    admin_option: true

# Note that here "db: postgres" specifies the database to connect to, not the
# database to grant privileges on (which is specified via the "objs" param)
- name: GRANT ALL PRIVILEGES ON DATABASE library TO librarian
  community.postgresql.postgresql_privs:
    login_db: postgres
    privs: ALL
    type: database
    obj: library
    role: librarian

# If objs is omitted for type "database", it defaults to the database
# to which the connection is established
- name: GRANT ALL PRIVILEGES ON DATABASE library TO librarian
  community.postgresql.postgresql_privs:
    login_db: library
    privs: ALL
    type: database
    role: librarian

# Available since version 2.7
# Objs must be set, ALL_DEFAULT to TABLES/SEQUENCES/TYPES/FUNCTIONS
# ALL_DEFAULT works only with privs=ALL
# For specific
- name: ALTER DEFAULT PRIVILEGES ON DATABASE library TO librarian
  community.postgresql.postgresql_privs:
    login_db: library
    objs: ALL_DEFAULT
    privs: ALL
    type: default_privs
    role: librarian
    grant_option: true

# Available since version 2.7
# Objs must be set, ALL_DEFAULT to TABLES/SEQUENCES/TYPES/FUNCTIONS
# ALL_DEFAULT works only with privs=ALL
# For specific
- name: ALTER DEFAULT PRIVILEGES ON DATABASE library TO reader, step 1
  community.postgresql.postgresql_privs:
    login_db: library
    objs: TABLES,SEQUENCES
    privs: SELECT
    type: default_privs
    role: reader

- name: ALTER DEFAULT PRIVILEGES ON DATABASE library TO reader, step 2
  community.postgresql.postgresql_privs:
    login_db: library
    objs: TYPES
    privs: USAGE
    type: default_privs
    role: reader

# Available since version 2.8
- name: GRANT ALL PRIVILEGES ON FOREIGN DATA WRAPPER fdw TO reader
  community.postgresql.postgresql_privs:
    login_db: library
    objs: fdw
    privs: ALL
    type: foreign_data_wrapper
    role: reader

# Available since community.postgresql 0.2.0
- name: GRANT ALL PRIVILEGES ON TYPE customtype TO reader
  community.postgresql.postgresql_privs:
    login_db: library
    objs: customtype
    privs: ALL
    type: type
    role: reader

# Available since version 2.8
- name: GRANT ALL PRIVILEGES ON FOREIGN SERVER fdw_server TO reader
  community.postgresql.postgresql_privs:
    login_db: test
    objs: fdw_server
    privs: ALL
    type: foreign_server
    role: reader

# Available since version 2.8
# Grant 'execute' permissions on all functions in schema 'common' to role 'caller'
- name: GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA common TO caller
  community.postgresql.postgresql_privs:
    type: function
    state: present
    privs: EXECUTE
    roles: caller
    objs: ALL_IN_SCHEMA
    schema: common

# Available since collection version 1.3.0
# Grant 'execute' permissions on all procedures in schema 'common' to role 'caller'
# Needs PostreSQL 11 or higher and community.postgresql 1.3.0 or higher
- name: GRANT EXECUTE ON ALL PROCEDURES IN SCHEMA common TO caller
  community.postgresql.postgresql_privs:
    type: procedure
    state: present
    privs: EXECUTE
    roles: caller
    objs: ALL_IN_SCHEMA
    schema: common

# Available since version 2.8
# ALTER DEFAULT PRIVILEGES FOR ROLE librarian IN SCHEMA library GRANT SELECT ON TABLES TO reader
# GRANT SELECT privileges for new TABLES objects created by librarian as
# default to the role reader.
# For specific
- name: ALTER privs
  community.postgresql.postgresql_privs:
    login_db: library
    schema: library
    objs: TABLES
    privs: SELECT
    type: default_privs
    role: reader
    target_roles: librarian

# Available since version 2.8
# ALTER DEFAULT PRIVILEGES FOR ROLE librarian IN SCHEMA library REVOKE SELECT ON TABLES FROM reader
# REVOKE SELECT privileges for new TABLES objects created by librarian as
# default from the role reader.
# For specific
- name: ALTER privs
  community.postgresql.postgresql_privs:
    login_db: library
    state: absent
    schema: library
    objs: TABLES
    privs: SELECT
    type: default_privs
    role: reader
    target_roles: librarian

# Available since community.postgresql 0.2.0
- name: Grant type privileges for pg_catalog.numeric type to alice
  community.postgresql.postgresql_privs:
    type: type
    roles: alice
    privs: ALL
    objs: numeric
    schema: pg_catalog
    login_db: acme

- name: Alter default privileges grant usage on schemas to datascience
  community.postgresql.postgresql_privs:
    login_db: test
    type: default_privs
    privs: usage
    objs: schemas
    role: datascience

# Available since community.postgresql 3.1.0
# Needs PostgreSQL 15 or higher
- name: GRANT SET ON PARAMETER log_destination,log_line_prefix TO logtest
  community.postgresql.postgresql_privs:
    login_db: logtest
    state: present
    privs: SET
    type: parameter
    objs: log_destination,log_line_prefix
    roles: logtest

- name: GRANT ALTER SYSTEM ON PARAMETER primary_conninfo,synchronous_standby_names TO replicamgr
  community.postgresql.postgresql_privs:
    login_db: replicamgr
    state: present
    privs: ALTER_SYSTEM
    type: parameter
    objs: primary_conninfo,synchronous_standby_names
    roles: replicamgr
z
queries:
  description: List of executed queries.
  returned: success
  type: list
  sample: ['REVOKE GRANT OPTION FOR INSERT ON TABLE "books" FROM "reader";']
N)	to_native)AnsibleModule)check_inputpg_quote_identifier)HAS_PSYCOPGPSYCOPG_VERSIONconnect_to_dbensure_required_libsget_conn_paramsget_server_versionpg_cursor_argspostgres_common_argument_spec)LooseVersionz3.0)Error)SELECTINSERTUPDATEDELETETRUNCATE
REFERENCESTRIGGERCREATECONNECT	TEMPORARYTEMPEXECUTEUSAGEALLSETALTER_SYSTEM)r!   r   r   r   r   r   r   r   )r!   r   r   r    )r!   r   )r!   r    )r   r    )TABLES	SEQUENCES	FUNCTIONSTYPESSCHEMASis i" )PUBLICCURRENT_USERSESSION_USERCURRENT_ROLEc                       e Zd Zy)r   N)__name__
__module____qualname__     y/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/postgresql/plugins/modules/postgresql_privs.pyr   r     s    r2   r   c                 D      fd} |_         |_        |_        |S )zPartial function applicationc                  \    j                         }|j                  |        | z   i |S N)copyupdate)g_argsg_kwargs
new_kwargsargsfkwargss      r3   gzpartial.<locals>.g  s0    [[]
(#4&=.X..r2   )r=   r<   r>   )r=   r<   r>   r?   s   ``` r3   partialr@     s$    /
 ACAFAHHr2   c                       e Zd ZdZd ZddZd Zd Zd Zd Z	d	 Z
d
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z	 ddZy)
ConnectionzAWrapper around a psycopg connection with some convenience methodsc                 |    |j                    _        | _        t        |       t	        ||j
                  d      }t        ||d      \   _        }  j                  j                  di t         _        t         j                         _        t         fdt        j                         D               _        y )NF)warn_db_default)
autocommitc              3   H   K   | ]  \  }}j                   |k\  s|  y wr6   )
pg_version).0implicit_roleversion_minselfs      r3   	<genexpr>z&Connection.__init__.<locals>.<genexpr>  s)      '
8m[\`\k\koz\zM'
s   ""r1   )login_dbdatabasemoduler   r   __dict__r   
connectioncursorr   r   rG   tupleVALID_IMPLICIT_ROLESitemspg_implicit_roles)rK   paramsrO   conn_paramsdummys   `    r3   __init__zConnection.__init__  s     	V$%ffoouU!.v{u!U,doo,,>~>,T__= "' '
<P<V<V<X'
 "
r2   Nc           	          	 | j                   j                  ||       y # t        $ r5}| j                  j	                  d|dt        |             Y d }~y d }~ww xY w)NzCannot execute SQL 'z': msg)rR   execute	ExceptionrO   	fail_jsonr   )rK   query
input_varses       r3   r^   zConnection.execute  sP    	]KKz2 	]KK!!uiXYl&[!\\	]s    	A+AAc                 8    | j                   j                          y r6   )rQ   commitrK   s    r3   re   zConnection.commit  s     r2   c                 8    | j                   j                          y r6   )rQ   rollbackrf   s    r3   rh   zConnection.rollback  s      "r2   c                 :    |j                         | j                  v S r6   )upperrV   )rK   rolnames     r3   is_implicit_rolezConnection.is_implicit_role	  s    }}$"8"888r2   c                     | j                  |      ryd}| j                  ||f       | j                  j                  dkD  S )NTz4SELECT 1 FROM pg_catalog.pg_roles WHERE rolname = %sr   )rl   r^   rR   rowcount)rK   rk   ra   s      r3   role_existszConnection.role_exists  s@      ) GUWJ'{{##a''r2   c                 l    d}| j                  ||f       | j                  j                         d   dkD  S )NzTSELECT count(*) c
                   FROM pg_catalog.pg_namespace WHERE nspname = %scr   )r^   rR   fetchone)rK   schemara   s      r3   schema_existszConnection.schema_exists  s7    FUVI&{{##%c*Q..r2   c                     |r5| j                  |      st        d|z        d}| j                  ||f       nd}| j                  |       | j                  j	                         D cg c]  }|d   	 c}S c c}w )NSchema "%s" does not exist.zSELECT relname
                       FROM pg_catalog.pg_class c
                       JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
                       WHERE nspname = %s AND relkind in ('r', 'v', 'm', 'p', 'f')zRSELECT relname FROM pg_catalog.pg_class WHERE relkind in ('r', 'v', 'm', 'p', 'f')relnamert   r   r^   rR   fetchallrK   rs   ra   ts       r3   get_all_tables_in_schemaz#Connection.get_all_tables_in_schema"  sw    %%f-9FBCCVE LL	*BELL&*kk&:&:&<=)===s   'A6c                     |r5| j                  |      st        d|z        d}| j                  ||f       n| j                  d       | j                  j	                         D cg c]  }|d   	 c}S c c}w )Nrv   zSELECT relname
                       FROM pg_catalog.pg_class c
                       JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
                       WHERE nspname = %s AND relkind = 'S'z;SELECT relname FROM pg_catalog.pg_class WHERE relkind = 'S'rw   rx   rz   s       r3   get_all_sequences_in_schemaz&Connection.get_all_sequences_in_schema2  so    %%f-9FBCC?E LL	*LLVW&*kk&:&:&<=)===s   %A4c                 ,   |rI| j                  |      st        d|z        d}| j                  dk\  r|dz  }| j                  ||f       n| j                  d       | j                  j                         D cg c]  }|d   d|d   d	 c}S c c}w )
Nrv   zSELECT p.proname, oidvectortypes(p.proargtypes) ptypes FROM pg_catalog.pg_proc p JOIN pg_namespace n ON n.oid = p.pronamespace WHERE nspname = %s鰭 z and p.prokind = 'f'zPSELECT p.proname, oidvectortypes(p.proargtypes) ptypes FROM pg_catalog.pg_proc pproname(ptypes))rt   r   rG   r^   rR   ry   rz   s       r3   get_all_functions_in_schemaz&Connection.get_all_functions_in_schema?  s    %%f-9FBCC*E
 &(//LL	*LLkl@D@T@T@VW1AiL!H+6WWWs   9Bc                 <   | j                   dk  rt        d      |r5| j                  |      st        d|z        d}| j                  ||f       nd}| j                  |       | j                  j                         D cg c]  }|d   d|d   d	 c}S c c}w )
Nr   z9PostgreSQL version must be >= 11 for type=procedure. Exitrv   zSELECT p.proname, oidvectortypes(p.proargtypes) ptypes FROM pg_catalog.pg_proc p JOIN pg_namespace n ON n.oid = p.pronamespace WHERE nspname = %s and p.prokind = 'p'zfSELECT p.proname, oidvectortypes(p.proargtypes) ptypes FROM pg_catalog.pg_proc p WHERE p.prokind = 'p'r   r   r   r   )rG   r   rt   r^   rR   ry   rz   s       r3   get_all_procedures_in_schemaz'Connection.get_all_procedures_in_schemaQ  s    ??V#STT%%f-9FBCC>E
 LL	*GELL@D@T@T@VW1AiL!H+6WWWs   Bc                     |rd}| j                  |||f       nd}| j                  |       | j                  j                         D cg c]  }|d   	 c}S c c}w )Na#  SELECT relacl::text
                       FROM pg_catalog.pg_class c
                       JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
                       WHERE nspname = %s AND relkind in ('r','p','v','m','f') AND relname = ANY (%s)
                       ORDER BY relnamez{SELECT relacl::text FROM pg_catalog.pg_class WHERE relkind in ('r','p','v','m','f') AND relname = ANY (%s) ORDER BY relnamerelaclr^   rR   ry   )rK   rs   tablesra   r{   s        r3   get_table_aclszConnection.get_table_aclsm  s[    +E
 LL 01(E LL%)[[%9%9%;<(<<<   	Ac                     |rd}| j                  |||f       nd}| j                  |       | j                  j                         D cg c]  }|d   	 c}S c c}w )Na  SELECT relacl::text
                       FROM pg_catalog.pg_class c
                       JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
                       WHERE nspname = %s AND relkind = 'S' AND relname = ANY (%s)
                       ORDER BY relnameziSELECT relacl::text FROM pg_catalog.pg_class WHERE  relkind = 'S' AND relname = ANY (%s) ORDER BY relnamer   r   )rK   rs   	sequencesra   r{   s        r3   get_sequence_aclszConnection.get_sequence_acls|  sZ    +E
 LL 34TELL%)[[%9%9%;<(<<<r   c                 
   |D cg c]  }|j                  dd      d    }}|rd}| j                  |||f       nd}| j                  ||       | j                  j                         D cg c]  }|d   	 c}S c c}w c c}w )Nr      r   a
  SELECT proacl::text
                       FROM pg_catalog.pg_proc p
                       JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
                       WHERE nspname = %s AND proname = ANY (%s)
                       ORDER BY proname, proargtypeszbSELECT proacl::text FROM pg_catalog.pg_proc WHERE proname = ANY (%s) ORDER BY proname, proargtypesproacl)splitr^   rR   ry   )rK   rs   function_signaturesr=   	funcnamesra   r{   s          r3   get_function_aclszConnection.get_function_acls  s    1DEAQWWS!_Q'E	E8E
 LL 345ELL,%)[[%9%9%;<(<< F =s   A;,B c                     d}| j                  ||f       | j                  j                         D cg c]  }|d   	 c}S c c}w )NzmSELECT nspacl::text FROM pg_catalog.pg_namespace
                   WHERE nspname = ANY (%s) ORDER BY nspnamenspaclr   )rK   schemasra   r{   s       r3   get_schema_aclszConnection.get_schema_acls  s?    @UWJ'%)[[%9%9%;<(<<<   Ac                     d}| j                  ||f       | j                  j                         D cg c]  }|d   	 c}S c c}w )NzlSELECT lanacl::text FROM pg_catalog.pg_language
                   WHERE lanname = ANY (%s) ORDER BY lannamelanaclr   )rK   	languagesra   r{   s       r3   get_language_aclszConnection.get_language_acls  ?    @UYL)%)[[%9%9%;<(<<<r   c                     d}| j                  ||f       | j                  j                         D cg c]  }|d   	 c}S c c}w )NznSELECT spcacl::text FROM pg_catalog.pg_tablespace
                   WHERE spcname = ANY (%s) ORDER BY spcnamespcaclr   )rK   tablespacesra   r{   s       r3   get_tablespace_aclszConnection.get_tablespace_acls  s?    @U[N+%)[[%9%9%;<(<<<r   c                     d}| j                  ||f       | j                  j                         D cg c]  }|d   	 c}S c c}w )NzlSELECT datacl::text FROM pg_catalog.pg_database
                   WHERE datname = ANY (%s) ORDER BY datnamedataclr   )rK   	databasesra   r{   s       r3   get_database_aclszConnection.get_database_acls  r   r   c                 `    d}| j                  ||f       | j                  j                         S )Na  SELECT roleid, grantor, member, admin_option
                   FROM pg_catalog.pg_auth_members am
                   JOIN pg_catalog.pg_roles r ON r.oid = am.roleid
                   WHERE r.rolname = ANY(%s)
                   ORDER BY roleid, grantor, memberr   )rK   groupsra   s      r3   get_group_membershipsz Connection.get_group_memberships  s.    7
 	UVI&{{##%%r2   c                     |rd}| j                  ||f       n| j                  d       | j                  j                         D cg c]  }|d   	 c}S c c}w )NzSELECT defaclacl::text
                       FROM pg_default_acl a
                       JOIN pg_namespace b ON a.defaclnamespace=b.oid
                       WHERE b.nspname = %s;z+SELECT defaclacl::text FROM pg_default_acl;	defaclaclr   )rK   rs   r<   ra   r{   s        r3   get_default_privszConnection.get_default_privs  sP    0E LL	*LLFG(,(<(<(>?1+???s   Ac                     d}| j                  ||f       | j                  j                         D cg c]  }|d   	 c}S c c}w )NzxSELECT fdwacl::text FROM pg_catalog.pg_foreign_data_wrapper
                   WHERE fdwname = ANY (%s) ORDER BY fdwnamefdwaclr   )rK   fdwsra   r{   s       r3   get_foreign_data_wrapper_aclsz(Connection.get_foreign_data_wrapper_acls  s?    @UTG$%)[[%9%9%;<(<<<r   c                     d}| j                  ||f       | j                  j                         D cg c]  }|d   	 c}S c c}w )NzrSELECT srvacl::text FROM pg_catalog.pg_foreign_server
                   WHERE srvname = ANY (%s) ORDER BY srvnamesrvaclr   )rK   fsra   r{   s       r3   get_foreign_server_aclsz"Connection.get_foreign_server_acls  s?    @URE"%)[[%9%9%;<(<<<r   c                     |rd}| j                  |||f       nd}| j                  |       | j                  j                         D cg c]  }|d   	 c}S c c}w )NzSELECT t.typacl::text FROM pg_catalog.pg_type t
                       JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
                       WHERE n.nspname = %s AND t.typname = ANY (%s) ORDER BY typnamezUSELECT typacl::text FROM pg_catalog.pg_type WHERE typname = ANY (%s) ORDER BY typnametypaclr   )rK   rs   typesra   r{   s        r3   get_type_aclszConnection.get_type_acls  sW    YE LL0kELL%)[[%9%9%;<(<<<r   c                     | j                   dk  rt        d      d}| j                  j                  ||f       | j                  j	                         D cg c]  }|d   	 c}S c c}w )NiI z9PostgreSQL version must be >= 15 for type=parameter. ExitzqSELECT paracl::text FROM pg_catalog.pg_parameter_acl
                   WHERE parname = ANY (%s) ORDER BY parnameparacl)rG   r   rR   r^   ry   )rK   
parametersra   r{   s       r3   get_parameter_aclszConnection.get_parameter_acls  s]    ??V#STT@EJ=1%)[[%9%9%;<(<<<s   A%c                 Z   |dk(  rt        | j                  |	      }n|dk(  rt        | j                  |	      }n|dv rt        | j                  |	      }n|dk(  r| j                  }n|dk(  r| j
                  }n|dk(  r| j                  }n|dk(  r| j                  }n|dk(  r| j                  }n||d	k(  rt        | j                  |	      }n`|d
k(  r| j                  }nN|dk(  r| j                  }n<|dk(  rt        | j                  |	      }n |dk(  r| j                  }nt        d|z        |sy|	rd|	j                  dd      z  nd}|dv r9g }|D ]1  }	 |j!                  dd      \  }}|j%                  |d|d|       3 n,|dv r|D cg c]
  }|d|d }}n|D cg c]  }d|z  	 }}|dk(  rdj'                  |      }n|d	k(  rdj'                  |      }n|dvr|D cg c]  }t)        |d       }}|*dj'                  |      j                  dd      d|d|}nHdj'                  |      j                  dd      d|j                  dd      ddj'                  |      }|sydj'                  |      }d}|rdj'                  d |D              } ||      }t+        |      j-                  |      j/                  |      j1                  |      j3                  |      j5                  |      j7                  |      j9                  |      j;                         }t<        j%                  |       | j?                  |        ||      }d }|jA                  |        |jA                  |        ||k7  S # t"        $ r t        d|z        w xY wc c}w c c}w c c}w )!a!  Manipulate database object privileges.

        :param obj_type: Type of database object to grant/revoke
                         privileges for.
        :param privs: Either a list of privileges to grant/revoke
                      or None if type is "group".
        :param objs: List of database objects to grant/revoke
                     privileges for.
        :param orig_objs: ALL_IN_SCHEMA or None.
        :param roles: List of role names.
        :param target_roles: List of role names to grant/revoke
                             default privileges as.
        :param state: "present" to grant privileges, "absent" to revoke.
        :param grant_option: Only for state "present": If True, set
                             grant/admin option. If False, revoke it.
                             If None, don't change grant option.
        :param schema_qualifier: Some object types ("TABLE", "SEQUENCE",
                                 "FUNCTION") must be qualified by schema.
                                 Ignored for other Types.
        tablesequencefunction	procedurers   language
tablespacerN   groupdefault_privsforeign_data_wrapperforeign_servertype	parameterz&Unsupported database object type "%s".F"%s""""Nr   r   z-Illegal function / procedure signature: "%s".z."z"()r   r   r   ,_ z ON c              3   &   K   | ]	  }d |z    yw)r   Nr1   )rH   rs     r3   rL   z.Connection.manipulate_privs.<locals>.<genexpr>I  s     ?Qfqj?s   c                     | yt        |       S )N )str)rc   s    r3   
nonesortedz/Connection.manipulate_privs.<locals>.nonesorted\  s     yq6Mr2   )key)!r@   r   r   r   r   r   r   r   r   r   r   r   r   r   r   replacer   r_   appendjoinr	   QueryBuilderfor_objtypewith_grant_optionfor_whomas_who
for_schemaset_whatfor_objsbuildexecuted_queriesr^   sort)rK   obj_typeprivsobjs	orig_objsrolestarget_rolesstategrant_optionschema_qualifierfail_on_role
get_statusquoted_schema_qualifierobj_idsobjr=   r<   or   ir   r   status_beforera   status_afterr   s                             r3   manipulate_privszConnection.manipulate_privs  s   . w !4!46FGJ# !7!79IJJ22 !7!79IJJ!--J#//J%11J#//J 33J( !7!79IJJ//;;J))55J !3!35EFJ$00J@8KLL Rb&+;+C+CC+N"Nhl00G RW!iiQ/GAt /F4PQR 66IMNA$;Q?NGN+/0avz0G0 wxx(H(xxH 88DKLq.q':LL $,/HHUO,C,CC,MyZqr,/HHUO,C,CC,MxO_O_`cehOiknkskst{k|} 88E? XX?,??F"4(U#["|,XhVF^Z/0XhXd^UW 	 	&U!$'	 	z*j),,A ! W ORU UVVW O0 Ms   NN"N#&N(Nr6   )NT)r.   r/   r0   __doc__rZ   r^   re   rh   rl   ro   rt   r|   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r1   r2   r3   rB   rB     s    K
"]!#
9
(/> >X$X8=======&	@==	== SW-r2   rB   c                   `    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zy)r   c                     d | _         d | _        d | _        d | _        d | _        || _        d | _        d | _        g | _        y r6   )	_grant_option	_for_whom_as_who	_set_what	_obj_type_state_schema_objsra   )rK   r   s     r3   rZ   zQueryBuilder.__init__j  sB    !

r2   c                     || _         | S r6   )r  )rK   r   s     r3   r   zQueryBuilder.for_objsu  s    
r2   c                 0    |d|z  | _         | S d| _         | S )Nz IN SCHEMA %sr   )r  )rK   rs   s     r3   r   zQueryBuilder.for_schemay  s(    393E/ LNr2   c                     || _         | S r6   )r   )rK   options     r3   r   zQueryBuilder.with_grant_option}  s    #r2   c                     || _         | S r6   )r   )rK   whos     r3   r   zQueryBuilder.for_whom  s    r2   c                     || _         | S r6   )r  )rK   r   s     r3   r   zQueryBuilder.as_who  s    #r2   c                     || _         | S r6   )r  )rK   whats     r3   r   zQueryBuilder.set_what  s    r2   c                     || _         | S r6   )r  )rK   objtypes     r3   r   zQueryBuilder.for_objtype  s     r2   c                     | j                   dk(  r| j                          n0| j                   dk(  r| j                          n| j                          dj                  | j                        S )Npresentabsent
)r  build_presentbuild_absentr   ra   rf   s    r3   r   zQueryBuilder.build  sQ    ;;)# [[H$yy$$r2   c           	      V   | j                   D ]  }| j                  rL| j                  j                  dj	                  | j                  | j
                  || j                               [| j                  j                  dj	                  | j
                  || j                                y )NDALTER DEFAULT PRIVILEGES FOR ROLE {0}{1} REVOKE ALL ON {2} FROM {3};7ALTER DEFAULT PRIVILEGES{0} REVOKE ALL ON {1} FROM {2};)r  r  ra   r   formatr  r   rK   r   s     r3   add_default_revokezQueryBuilder.add_default_revoke  s    :: 		fC||

!!Zaabfbnbnbfbnbnpsbfbpbprs
 

!!MTTUYUaUacfUYUcUcef		fr2   c                 P   | j                   r?| j                  dk(  r| j                  dxx   dz  cc<   y | j                  dxx   dz  cc<   y | j                   du r| j                  dxx   dz  cc<   | j                  dk(  r@| j                  j                  dj	                  | j
                  | j                               y | j                  dk(  s@| j                  j                  d	j	                  | j
                  | j                               y y | j                  dxx   dz  cc<   y )
Nr   z WITH ADMIN OPTION;z WITH GRANT OPTION;F;z%REVOKE ADMIN OPTION FOR {0} FROM {1};r   z%REVOKE GRANT OPTION FOR {0} FROM {1};)r   r  ra   r   r  r  r   rf   s    r3   add_grant_optionzQueryBuilder.add_grant_option  s    ~~(

2"77

2"775(JJrNc!N~~(

!!"I"P"PQUQ_Q_aeaoao"pq^^6

!!"I"P"PQUQ_Q_aeaoao"pq 7 JJrNc!Nr2   c           
         | j                   D ]  }| j                  rW| j                  j                  dj	                  | j                  | j
                  | j                  || j                               nK| j                  j                  dj	                  | j
                  | j                  || j                               | j                           y )Nz@ALTER DEFAULT PRIVILEGES FOR ROLE {0}{1} GRANT {2} ON {3} TO {4}z3ALTER DEFAULT PRIVILEGES{0} GRANT {1} ON {2} TO {3})	r  r  ra   r   r  r  r  r   r!  r  s     r3   add_default_privzQueryBuilder.add_default_priv  s    :: 	$C||

!!V]]^b^j^j^b^j^j^b^l^l^a^b^l^l	no 

!!IPPQUQ]Q]QUQ_Q_QTQUQ_Q_ab
 !!#	$r2   c                    | j                   dk(  r!| j                          | j                          y | j                  j	                  dj                  | j                  | j                               | j                          y )Nr   zGRANT {0} TO {1})	r  r  r#  ra   r   r  r  r   r!  rf   s    r3   r  zQueryBuilder.build_present  sZ    >>_,##%!!#JJ077WX!!#r2   c           	         | j                   dk(  rg | _        dD ]  }| j                  rL| j                  j                  dj	                  | j                  | j
                  || j                               [| j                  j                  dj	                  | j
                  || j                                y | j                  j                  dj	                  | j                  | j                               y )Nr   )r$   r&   r%   r'   r  r  zREVOKE {0} FROM {1};)r  ra   r  r   r  r  r   r  r  s     r3   r  zQueryBuilder.build_absent  s    >>_,DJD 	j<<JJ%%^eefjfrfrfjfrfrtwfjftftvw
 JJ%%QXXY]YeYegjY]YgYgij	j JJ4;;DNNDNN[\r2   N)r.   r/   r0   rZ   r   r   r   r   r   r   r   r   r  r!  r#  r  r  r1   r2   r3   r   r   i  sJ    	%
f"$"$]r2   r   c                     t               } | j                  t        ddddgddddddddg      t        d	d	d
g      t        ddg      t        dg d      t        ddg      t        d      t        ddg      t        d      t        d      t        dddg      t        dddd      t        dd      t        dd             t        | d      }|j                  d   }t        dd |j                        }|j                  r/|j                  r|j                  d!"       |j                  |_        |j
                  d#v r<|j                  d$k(  s|j                  d%k(  rd |_
        nA|j                  xs d&|_
        n+|j                  r|j                  d'|j
                  z  "       |j                  d(k(  r-|j
                  d)vr|j                  d*|j
                  z  "       |j
                  dk(  r |j                  xs |j                  |_	        n+|j                  s|j                  d+|j
                  z  "       |j
                  d,k(  r|j                  r>|j                  d-"       n+|j                  s|j                  d.|j
                  z  "       |j                  s7t        ||j                  |j                   |j"                  |j                         t%        ||      }|j"                  r)	 |j&                  j)                  d/|j"                  z         	 |j                  rit3        d3 |j                  j5                  d4      D              j7                  t8              s+|j                  d5j;                  t8              z  "       nd d }|j                  d(k(  r|j
                  dk(  r|j=                  |j                        }n|j
                  d6k(  r|j?                  |j                        }nU|j
                  d7k(  r|jA                  |j                        }n*|j
                  d8k(  r|jC                  |j                        }|jD                  d9k\  r|j
                  dk(  rd:}n|j
                  d6k(  rd;}nr|j
                  d7k(  rd<}n_|j
                  d8k(  rOd=}nK|j
                  d>k(  r|j                  d?k(  r3tF        jI                  d@       t3        tF        jK                               }nvt3        dA |j                  j5                  d4      D              }|j7                  tF              s6|j                  dB|j;                  tF        jK                               z  "       t3        fdC|D              }||k(  sk|j                  dDjM                  ||      "       nH|j                  j5                  d4      }|j
                  dEv r|D 	cg c]  }	|	jO                  dFd4       }}	g }
|j                  j5                  d4      }|D ]  }|jQ                  |      rY|jS                  |      r#|
jU                  dG|jW                         z         H|
jU                  dH|jO                  dIdJ      z         m|r|j                  dK|z  "       |jY                  dL|z          |
s(|jY                  dM       |j[                  dt\        N       |j                   r |j
                  d>k(  s|jY                  dO       |j                   r|j                   j5                  d4      }nd }|j_                  |j
                  ||
||j`                  |jb                  |j                  |P
      }|jj                  ss|jg                          n|jm                          |j&                  jo                          |jp                  jo                          |j[                  t\        N       y # t*        $ rI}|j                  d0|j"                  d1t-        |      t/        j0                         2       Y d }~"d }~ww xY wc c}	w # td        $ rI}|jg                          |j                  t-        |      t/        j0                         2       Y d }~"d }~wth        $ r6}|jg                          |j                  t-        |      "       Y d }~_d }~ww xY w)QNr   TdbrN   z5.0.0zcommunity.postgresql)nameversioncollection_name)r   requiredaliasesdeprecated_aliasesr  r  )defaultchoicesFpriv)r+  r,  r   )r   r   r   r   rN   rs   r   r   r   r   r   r   r   r   r   )r+  rolebooladmin_option)r+  r   r,  r   z4.0.0zcommunity.postgreql)r.  no_logremoved_in_versionremoved_from_collection)r   r.  )rM   r   r   r   r   rs   r   session_roler   r   passwordr   trust_input)argument_specsupports_check_moder   Paramsr1   z]Use the "password" or "login_password" option but not both to pass a password to log in with.r\   )r   r   r   r   r   r   r   znot-specifiedpublicz/Argument "schema" is not allowed for type "%s".ALL_IN_SCHEMA)r   r   r   r   zpArgument "objs": ALL_IN_SCHEMA can be used only for type: table, sequence, function or procedure, %s was passed.z*Argument "objs" is required for type "%s".r   z1Argument "privs" is not allowed for type "group".z+Argument "privs" is required for type "%s".zSET ROLE "%s"zCould not switch to role z: )r]   	exceptionc              3   <   K   | ]  }|j                           y wr6   rj   )rH   prs     r3   rL   zmain.<locals>.<genexpr>T  s     FRbhhjF   r   z Invalid privileges specified: %sr   r   r   i_ zALL TABLES IN SCHEMAzALL SEQUENCES IN SCHEMAzALL FUNCTIONS IN SCHEMAzALL PROCEDURES IN SCHEMAr   ALL_DEFAULTr(   c              3   <   K   | ]  }|j                           y wr6   rA  )rH   r   s     r3   rL   zmain.<locals>.<genexpr>t  s      J JrC  z Invalid Object set specified: %sc              3   T   K   | ]  }j                  t        |         s| ! y wr6   )issubsetVALID_DEFAULT_OBJS)rH   r   r   s     r3   rL   zmain.<locals>.<genexpr>y  s#     .nsennUghkUlFms.ns   ((z@Invalid priv specified. Valid object for priv: {0}. Objects: {1}r   :z%sr   r   r   zRole '%s' does not existz!Role '%s' does not exist, pass itz&No valid roles provided, nothing to do)changedquerieszf"target_roles" will be ignored Argument "type: default_privs" is required for usage of "target_roles".)
r   r   r   r   r   r   r   r   r   r   )9r   r8   dictr   rW   r   r8  login_passwordr`   r   rs   rM   r   r9  r   r   r   r7  rB   rR   r^   r_   r   	traceback
format_exc	frozensetr   rG  VALID_PRIVS
differencer|   r~   r   r   rG   rH  popkeysr  r   ro   rl   r   rj   warn	exit_jsonr   r   r   r   r   rh   PsycopgError
check_modere   closerQ   )r:  rO   r   pconnrc   r   r   valid_objects_for_privr   r   	roles_rawr   r   rJ  r   s                  @r3   mainr^    s   13M54$
9K"#9 #"#9
a 
 9y(.CDEF84'*+ 55'2U#D6(35)5)5v#1"24 b)0.CE vt4fd3W  ,\ # F
 ==0L 	Xr6==)A
 	zz "F G:: 	vvXX66Y!((o"=AHxx+8AH	
 .017 	8
 	vv QVV3a%a .017 	8
 	vv%1::VV .017 	8 	vv77 "5 6WW .017 	8 ==FAGGQ^^Q^^QXXN a D~~	GKK!.. @Ag+77F177==3EFFE>>+.  %G%JZJZ[fJg%g hE	66_$vv 44QXX>:%77A:%77A;&88B%'66W$ 6IVVz) 9IVVz) 9IVV{* :IVV&vv&"&&y1 !3!8!8!:;  JS8I JJ}}%78$$>QcQhQhQjAkk % m &/.nd.n%n")T1  Zaa.6 ! 7 66<<$D vv229=>#C->> GGMM#&	 	IA"((+ LL	!12LL!))C*>!>?$$)Ca)G$HKK Ca GH	I KK@AU4DE >>!&&O";KK b c >>>>//4LL''VV%''XX% ( 
* KKOO
W.>?i  	GannV_`aVb!cox  pD  pD  pF  G  G	Gj ?^  MYq\Y5I5I5KLL +Yq\**+sP   =(_: &Ka 'a E?a :	a>aaa 	c#>b!!c#-+cc#__main__),
__future__r   r   r   r   __metaclass__DOCUMENTATIONEXAMPLESRETURNrN  ansible.module_utils._textr   ansible.module_utils.basicr   Fansible_collections.community.postgresql.plugins.module_utils.databaser   r	   Fansible_collections.community.postgresql.plugins.module_utils.postgresr
   r   r   r   r   r   r   r   Eansible_collections.community.postgresql.plugins.module_utils.versionr   psycopg2r   rW  psycopgrP  rQ  rH  rT   r   r_   r@   objectrB   r   r^  r.   r1   r2   r3   <module>rm     s    A @`Drh
  0 4	 	 	 ?\%%88.- k l t#G#5/!4	8 
 #$(-(-(.2 
  	I 	
- -Ds]6 s]lc@L zF r2   