
    VhF+                         d dl mZmZmZ eZdZdZdZd dl	m
Z
mZ d dlmZmZ d dlmZmZ d dlmZ d d	lmZ  G d
 de      Z G d de      Z G d de      Z e       Zy)    )absolute_importdivisionprint_functiona  
name: bitwarden
author:
  - Jonathan Lung (@lungj) <lungj@heresjono.com>
requirements:
  - bw (command line utility)
  - be logged into bitwarden
  - bitwarden vault unlocked
  - E(BW_SESSION) environment variable set
short_description: Retrieve secrets from Bitwarden
version_added: 5.4.0
description:
  - Retrieve secrets from Bitwarden.
options:
  _terms:
    description: Key(s) to fetch values for from login info.
    required: true
    type: list
    elements: str
  search:
    description:
      - Field to retrieve, for example V(name) or V(id).
      - If set to V(id), only zero or one element can be returned. Use the Jinja C(first) filter to get the only list element.
      - If set to V(None) or V(''), or if O(_terms) is empty, records are not filtered by fields.
    type: str
    default: name
    version_added: 5.7.0
  field:
    description: Field to fetch. Leave unset to fetch whole response.
    type: str
  collection_id:
    description:
      - Collection ID to filter results by collection. Leave unset to skip filtering.
      - O(collection_id) and O(collection_name) are mutually exclusive.
    type: str
    version_added: 6.3.0
  collection_name:
    description:
      - Collection name to filter results by collection. Leave unset to skip filtering.
      - O(collection_id) and O(collection_name) are mutually exclusive.
    type: str
    version_added: 10.4.0
  organization_id:
    description: Organization ID to filter results by organization. Leave unset to skip filtering.
    type: str
    version_added: 8.5.0
  bw_session:
    description: Pass session key instead of reading from env.
    type: str
    version_added: 8.4.0
  result_count:
    description:
      - Number of results expected for the lookup query. Task will fail if O(result_count) is set but does not match the number
        of query results. Leave empty to skip this check.
    type: int
    version_added: 10.4.0
aX  
- name: "Get 'password' from all Bitwarden records named 'a_test'"
  ansible.builtin.debug:
    msg: >-
      {{ lookup('community.general.bitwarden', 'a_test', field='password') }}

- name: "Get 'password' from Bitwarden record with ID 'bafba515-af11-47e6-abe3-af1200cd18b2'"
  ansible.builtin.debug:
    msg: >-
      {{ lookup('community.general.bitwarden', 'bafba515-af11-47e6-abe3-af1200cd18b2', search='id', field='password') | first }}

- name: "Get 'password' from all Bitwarden records named 'a_test' from collection"
  ansible.builtin.debug:
    msg: >-
      {{ lookup('community.general.bitwarden', 'a_test', field='password', collection_id='bafba515-af11-47e6-abe3-af1200cd18b2') }}

- name: "Get list of all full Bitwarden records named 'a_test'"
  ansible.builtin.debug:
    msg: >-
      {{ lookup('community.general.bitwarden', 'a_test') }}

- name: "Get custom field 'api_key' from all Bitwarden records named 'a_test'"
  ansible.builtin.debug:
    msg: >-
      {{ lookup('community.general.bitwarden', 'a_test', field='api_key') }}

- name: "Get 'password' from all Bitwarden records named 'a_test', using given session key"
  ansible.builtin.debug:
    msg: >-
      {{ lookup('community.general.bitwarden', 'a_test', field='password', bw_session='bXZ9B5TXi6...') }}

- name: "Get all Bitwarden records from collection"
  ansible.builtin.debug:
    msg: >-
      {{ lookup('community.general.bitwarden', None, collection_id='bafba515-af11-47e6-abe3-af1200cd18b2') }}

- name: "Get all Bitwarden records from collection"
  ansible.builtin.debug:
    msg: >-
      {{ lookup('community.general.bitwarden', None, collection_name='my_collections/test_collection') }}

- name: "Get Bitwarden record named 'a_test', ensure there is exactly one match"
  ansible.builtin.debug:
    msg: >-
      {{ lookup('community.general.bitwarden', 'a_test', result_count=1) }}
a?  
_raw:
  description:
    - A one-element list that contains a list of requested fields or JSON objects of matches.
    - If you use C(query), you get a list of lists. If you use C(lookup) without C(wantlist=true), this always gets reduced
      to a list of field values or JSON objects.
  type: list
  elements: list
)PopenPIPE)AnsibleErrorAnsibleOptionsError)to_bytesto_text)AnsibleJSONDecoder)
LookupBasec                       e Zd Zy)BitwardenExceptionN)__name__
__module____qualname__     n/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/general/plugins/lookup/bitwarden.pyr   r      s    r   r   c                       e Zd ZddZed        Zed        Zej                  d        Zed        ZddZ	ddZ
dd	Zdd
edee   fdZy)	Bitwardenc                      || _         d | _        y N)	_cli_path_session)selfpaths     r   __init__zBitwarden.__init__   s    r   c                     | j                   S r   )r   r   s    r   cli_pathzBitwarden.cli_path   s    ~~r   c                     | j                   S r   r   r    s    r   sessionzBitwarden.session   s    }}r   c                     || _         y r   r#   )r   values     r   r$   zBitwarden.session   s	    r   c                 x    | j                  dgd      \  }}t               j                  |      d   }|d   dk(  S )Nstatus )stdinr   unlocked)_runr   
raw_decode)r   outerrdecodeds       r   r+   zBitwarden.unlocked   sB    99hZr92S$&11#6q9x J..r   Nc                    | j                   r|d| j                   gz  }t        | j                  g|z   t        t        t              }|j	                  t        |            \  }}|j                         }||k7  r.t        |      dkD  r|d   dk(  r|d   dk(  rd|v ry	t        |      t        |d
      t        |d
      fS )Nz	--session)stdoutstderrr*      r   get   items
   Not found.)nullr)   surrogate_or_strict)errors)
r$   r   r!   r   communicater
   waitlenr   r   )r   argsr*   expected_rcpr.   r/   rcs           r   r,   zBitwarden._run   s    <<[$,,//D4==/D(d$O==%1SVVX4y1}aE!1d1g6GM]`L`!$S))s#8973Od;eeer   c                 r   |dk(  rdd|g}nddg}|r|j                  d|g       |r|j                  d|g       |r|j                  d|g       | j                  |      \  }}t               j                  |      d	   }|dk(  r|g }n|g}|D 	cg c]  }	|r|r|	j	                  |      |k(  r|	 c}	S c c}	w )
zDReturn matching records whose search_field is equal to key.
        idr5   r7   listitems--searchz--collectionid--organizationidr   )extendr,   r   r-   r5   )
r   search_valuesearch_fieldcollection_idorganization_idparamsr.   r/   initial_matchesr7   s
             r   _get_matcheszBitwarden._get_matches   s    
 4V\2Fg&Fz<89MM+];<MM-?@99V$S -.99#>qA4&"$#2"3 "1 c#<488L;QUa;a  c 	c cs   !B4c                 P   | j                  ||||      }|s|S g }|D ]q  }d|v r/d}	|d   D ]"  }
||
d   k(  s|j                  |
d          d}	 n |	r6d|v r||d   v r|j                  |d   |          Y||v s^|j                  ||          s |r|st        d| d|       |S )	zReturn a list of the specified field for records whose search_field match search_value
        and filtered by collection if collection has been provided.

        If field is None, return the whole record for each match.
        fieldsFnamer&   Tloginzfield z does not exist in )rO   appendr   )r   fieldrI   rJ   rK   rL   matchesfield_matchesmatchcustom_field_foundcustom_fields              r   	get_fieldzBitwarden.get_field   s     ##L,_N 	E5 %*"$)(O LV 44%,,\'-BC-1*	
 &%EU7^$;$$U7^E%:;~$$U5\2!	$ =w.A,PQQr   collection_namereturnc                 :   ddd|g}|r|j                  d|g       | j                  |      \  }}t               j                  |      d   }|D cg c]@  }t	        |j                  d            j                         |j                         k(  r|d   B c}S c c}w )zJReturn matching IDs of collections whose name is equal to collection_name.rD   collectionsrF   rG   r   rR   rC   )rH   r,   r   r-   strr5   lower)r   r\   rL   rM   r.   r/   rN   r7   s           r   get_collection_idszBitwarden.get_collection_ids   s     -_EMM-?@99V$S -.99#>qA (7 Mttxx'(..0O4I4I4KK T
 M 	M Ms   AB)bw)Nr   NN)rR   NNr   )r   r   r   r   propertyr!   r$   setterr+   r,   rO   r[   r`   rD   rb   r   r   r   r   r      s         ^^  / /
fc@BM# MPTUXPY Mr   r   c                       e Zd ZddZy)LookupModuleNc                    | j                  ||       | j                  d      }| j                  d      }| j                  d      }| j                  d      }| j                  d      }| j                  d      }	| j                  d      t        _        t        j                  st        d	      |sd g}|r|rt        d
      |r#t        j                  ||      }
|
st        d      |g}
|
D cg c]"  }|D ]  }t        j                  |||||       $ }}}|D ].  }|	t        |      |	k7  st        dt        |       d|	 d       |S c c}}w )N)var_optionsdirectrU   searchrK   r\   rL   result_count
bw_sessionz(Bitwarden Vault locked. Run 'bw unlock'.z='collection_name' and 'collection_id' are mutually exclusive!zNo matching collections found!z/Number of results doesn't match result_count! (z != ))set_options
get_option
_bitwardenr$   r+   r   r	   rb   r   r[   r=   )r   terms	variableskwargsrU   rJ   rK   r\   rL   rm   collection_idstermresultsresults                 r   runzLookupModule.run  sw   Yv>(x08//*;<//*;<~6!__\:
""IJJFE}%&eff'::?O\N!()IJJ+_N "0

    lM?[
[
 
  	hF'CK<,G(Ec&k]RVWcVddefh h	h
 
s   0'Erd   )r   r   r   rz   r   r   r   rh   rh      s    $r   rh   N)
__future__r   r   r   type__metaclass__DOCUMENTATIONEXAMPLESRETURN
subprocessr   r   ansible.errorsr   r	   +ansible.module_utils.common.text.convertersr
   r   ansible.parsing.ajsonr   ansible.plugins.lookupr   r   objectr   rh   rr   r   r   r   <module>r      sn   
 C B8t-^
 # < I 4 -	 	vM vMr&: &R [
r   