---
- name: fail to run the module without become
  win_credential:
    name: '{{ test_hostname }}'
    type: domain_password
    username: DOMAIN\username
    secret: password
    state: present
  register: fail_no_become
  failed_when: '"Failed to access the user''s credential store, run the module with become" not in fail_no_become.msg'

- name: create domain user credential (check mode)
  win_credential:
    name: '{{ test_hostname }}'
    type: domain_password
    username: DOMAIN\username
    secret: password
    state: present
  register: domain_user_check
  check_mode: True
  vars: &become_vars
    ansible_become: True
    ansible_become_method: runas
    ansible_become_user: '{{ ansible_user }}'
    ansible_become_pass: '{{ ansible_password }}'

- name: get result of create domain user credential (check mode)
  test_cred_facts:
    name: '{{ test_hostname }}'
    type: domain_password
  register: domain_user_actual_check
  vars: *become_vars

- name: asset create domain user credential (check mode)
  assert:
    that:
    - domain_user_check is changed
    - not domain_user_actual_check.exists

- name: create domain user credential
  win_credential:
    name: '{{ test_hostname }}'
    type: domain_password
    username: DOMAIN\username
    secret: password
    state: present
  register: domain_user
  vars: *become_vars

- name: get result of create domain user credential
  test_cred_facts:
    name: '{{ test_hostname }}'
    type: domain_password
  register: domain_user_actual
  vars: *become_vars

- name: asset create domain user credential
  assert:
    that:
    - domain_user is changed
    - domain_user_actual.exists
    - domain_user_actual.alias == None
    - domain_user_actual.attributes == []
    - domain_user_actual.comment == None
    - domain_user_actual.name == test_hostname
    - domain_user_actual.persistence == "LocalMachine"
    - domain_user_actual.secret == ""
    - domain_user_actual.type == "DomainPassword"
    - domain_user_actual.username == "DOMAIN\\username"

- name: create domain user credential again always update
  win_credential:
    name: '{{ test_hostname }}'
    type: domain_password
    username: DOMAIN\username
    secret: password
    state: present
  register: domain_user_again_always
  vars: *become_vars

- name: create domain user credential again on_create
  win_credential:
    name: '{{ test_hostname }}'
    type: domain_password
    username: DOMAIN\username
    secret: password
    update_secret: on_create
    state: present
  register: domain_user_again_on_create
  vars: *become_vars

- name: assert create domain user credential again
  assert:
    that:
    - domain_user_again_always is changed
    - not domain_user_again_on_create is changed

- name: update credential (check mode)
  win_credential:
    name: '{{ test_hostname }}'
    type: domain_password
    username: DOMAIN\username2
    alias: ansible
    attributes:
    - name: attribute 1
      data: attribute 1 value
    - name: attribute 2
      data: '{{ "attribute 2 value" | b64encode }}'
      data_format: base64
    comment: Credential comment
    persistence: enterprise
    state: present
  register: update_cred_check
  check_mode: True
  vars: *become_vars

- name: get result of update credential (check mode)
  test_cred_facts:
    name: '{{ test_hostname }}'
    type: domain_password
  register: update_cred_actual_check
  vars: *become_vars

- name: assert update credential (check mode)
  assert:
    that:
    - update_cred_check is changed
    - update_cred_actual_check.exists
    - update_cred_actual_check.alias == None
    - update_cred_actual_check.attributes == []
    - update_cred_actual_check.comment == None
    - update_cred_actual_check.name == test_hostname
    - update_cred_actual_check.persistence == "LocalMachine"
    - update_cred_actual_check.secret == ""
    - update_cred_actual_check.type == "DomainPassword"
    - update_cred_actual_check.username == "DOMAIN\\username"

- name: update credential
  win_credential:
    name: '{{ test_hostname }}'
    type: domain_password
    username: DOMAIN\username2
    alias: ansible
    attributes:
    - name: attribute 1
      data: attribute 1 value
    - name: attribute 2
      data: '{{ "attribute 2 value" | b64encode }}'
      data_format: base64
    comment: Credential comment
    persistence: enterprise
    state: present
  register: update_cred
  vars: *become_vars

- name: get result of update credential
  test_cred_facts:
    name: '{{ test_hostname }}'
    type: domain_password
  register: update_cred_actual
  vars: *become_vars

- name: assert update credential
  assert:
    that:
    - update_cred is changed
    - update_cred_actual.exists
    - update_cred_actual.alias == "ansible"
    - update_cred_actual.attributes|count == 2
    - update_cred_actual.attributes[0].name == "attribute 1"
    - update_cred_actual.attributes[0].data == "attribute 1 value"|b64encode
    - update_cred_actual.attributes[1].name == "attribute 2"
    - update_cred_actual.attributes[1].data == "attribute 2 value"|b64encode
    - update_cred_actual.comment == "Credential comment"
    - update_cred_actual.name == test_hostname
    - update_cred_actual.persistence == "Enterprise"
    - update_cred_actual.secret == ""
    - update_cred_actual.type == "DomainPassword"
    - update_cred_actual.username == "DOMAIN\\username2"

- name: update credential again
  win_credential:
    name: '{{ test_hostname }}'
    type: domain_password
    username: DOMAIN\username2
    alias: ansible
    attributes:
    - name: attribute 1
      data: attribute 1 value
    - name: attribute 2
      data: '{{ "attribute 2 value" | b64encode }}'
      data_format: base64
    comment: Credential comment
    persistence: enterprise
    state: present
  register: update_cred_again
  vars: *become_vars

- name: assert update credential again
  assert:
    that:
    - not update_cred_again is changed

- name: add new attribute
  win_credential:
    name: '{{ test_hostname }}'
    type: domain_password
    username: DOMAIN\username2
    alias: ansible
    attributes:
    - name: attribute 1
      data: attribute 1 value
    - name: attribute 2
      data: '{{ "attribute 2 value" | b64encode }}'
      data_format: base64
    - name: attribute 3
      data: attribute 3 value
    comment: Credential comment
    persistence: enterprise
    state: present
  register: add_attribute
  vars: *become_vars

- name: get result of add new attribute
  test_cred_facts:
    name: '{{ test_hostname }}'
    type: domain_password
  register: add_attribute_actual
  vars: *become_vars

- name: assert add new attribute
  assert:
    that:
    - add_attribute is changed
    - add_attribute_actual.attributes|count == 3
    - add_attribute_actual.attributes[0].name == "attribute 1"
    - add_attribute_actual.attributes[0].data == "attribute 1 value"|b64encode
    - add_attribute_actual.attributes[1].name == "attribute 2"
    - add_attribute_actual.attributes[1].data == "attribute 2 value"|b64encode
    - add_attribute_actual.attributes[2].name == "attribute 3"
    - add_attribute_actual.attributes[2].data == "attribute 3 value"|b64encode

- name: remove attribute
  win_credential:
    name: '{{ test_hostname }}'
    type: domain_password
    username: DOMAIN\username2
    alias: ansible
    attributes:
    - name: attribute 1
      data: attribute 1 value
    - name: attribute 2
      data: '{{ "attribute 2 value" | b64encode }}'
      data_format: base64
    comment: Credential comment
    persistence: enterprise
    state: present
  register: remove_attribute
  vars: *become_vars

- name: get result of remove attribute
  test_cred_facts:
    name: '{{ test_hostname }}'
    type: domain_password
  register: remove_attribute_actual
  vars: *become_vars

- name: assert remove attribute
  assert:
    that:
    - remove_attribute is changed
    - remove_attribute_actual.attributes|count == 2
    - remove_attribute_actual.attributes[0].name == "attribute 1"
    - remove_attribute_actual.attributes[0].data == "attribute 1 value"|b64encode
    - remove_attribute_actual.attributes[1].name == "attribute 2"
    - remove_attribute_actual.attributes[1].data == "attribute 2 value"|b64encode

- name: edit attribute
  win_credential:
    name: '{{ test_hostname }}'
    type: domain_password
    username: DOMAIN\username2
    alias: ansible
    attributes:
    - name: attribute 1
      data: attribute 1 value new
    - name: attribute 2
      data: '{{ "attribute 2 value" | b64encode }}'
      data_format: base64
    comment: Credential comment
    persistence: enterprise
    state: present
  register: edit_attribute
  vars: *become_vars

- name: get result of edit attribute
  test_cred_facts:
    name: '{{ test_hostname }}'
    type: domain_password
  register: edit_attribute_actual
  vars: *become_vars

- name: assert remove attribute
  assert:
    that:
    - edit_attribute is changed
    - edit_attribute_actual.attributes|count == 2
    - edit_attribute_actual.attributes[0].name == "attribute 1"
    - edit_attribute_actual.attributes[0].data == "attribute 1 value new"|b64encode
    - edit_attribute_actual.attributes[1].name == "attribute 2"
    - edit_attribute_actual.attributes[1].data == "attribute 2 value"|b64encode

- name: remove credential (check mode)
  win_credential:
    name: '{{ test_hostname }}'
    type: domain_password
    state: absent
  register: remove_cred_check
  check_mode: True
  vars: *become_vars

- name: get result of remove credential (check mode)
  test_cred_facts:
    name: '{{ test_hostname }}'
    type: domain_password
  register: remove_cred_actual_check
  vars: *become_vars

- name: assert remove credential (check mode)
  assert:
    that:
    - remove_cred_check is changed
    - remove_cred_actual_check.exists

- name: remove credential
  win_credential:
    name: '{{ test_hostname }}'
    type: domain_password
    state: absent
  register: remove_cred
  vars: *become_vars

- name: get result of remove credential
  test_cred_facts:
    name: '{{ test_hostname }}'
    type: domain_password
  register: remove_cred_actual
  vars: *become_vars

- name: assert remove credential
  assert:
    that:
    - remove_cred is changed
    - not remove_cred_actual.exists

- name: remove credential again
  win_credential:
    name: '{{ test_hostname }}'
    type: domain_password
    state: absent
  register: remove_cred_again
  vars: *become_vars

- name: assert remove credential again
  assert:
    that:
    - not remove_cred_again is changed

# https://github.com/ansible/ansible/issues/67278
- name: create credential with wildcard
  win_credential:
    name: '*.{{ test_hostname }}'
    type: domain_password
    username: DOMAIN\username
    secret: password
    state: present
    persistence: enterprise
  register: wildcard_cred
  vars: *become_vars

- name: get result of create credential with wildcard
  test_cred_facts:
    name: '*.{{ test_hostname }}'
    type: domain_password
  register: wildcard_cred_actual
  vars: *become_vars

- name: assert create credential with wildcard
  assert:
    that:
    - wildcard_cred is changed
    - wildcard_cred_actual.name == '*.' ~ test_hostname

- name: remove credential with wildcard
  win_credential:
    name: '*.{{ test_hostname }}'
    type: domain_password
    state: absent
  register: wildcard_remove
  vars: *become_vars

- name: get result of remove credential with wildcard
  test_cred_facts:
    name: '*.{{ test_hostname }}'
    type: domain_password
  register: wildcard_remove_actual
  vars: *become_vars

- name: assert remove credential with wildcard
  assert:
    that:
    - wildcard_remove is changed
    - not wildcard_remove_actual.exists

- name: create generic password (check mode)
  win_credential:
    name: '{{ test_hostname }}'
    type: generic_password
    persistence: enterprise
    username: genericuser
    secret: genericpass
    state: present
  register: generic_password_check
  check_mode: True
  vars: *become_vars

- name: get result of create generic password (check mode)
  test_cred_facts:
    name: '{{ test_hostname }}'
    type: generic_password
  register: generic_password_actual_check
  vars: *become_vars

- name: assert result of create generic password (check mode)
  assert:
    that:
    - generic_password_check is changed
    - not generic_password_actual_check.exists

- name: create generic password
  win_credential:
    name: '{{ test_hostname }}'
    type: generic_password
    persistence: enterprise
    username: genericuser
    secret: genericpass
    state: present
  register: generic_password
  vars: *become_vars

- name: get result of create generic password
  test_cred_facts:
    name: '{{ test_hostname }}'
    type: generic_password
  register: generic_password_actual
  vars: *become_vars

- name: set encoded password result
  set_fact:
    encoded_pass: '{{ "genericpass" | string | b64encode(encoding="utf-16-le") }}'

- name: assert create generic password
  assert:
    that:
    - generic_password is changed
    - generic_password_actual.exists
    - generic_password_actual.alias == None
    - generic_password_actual.attributes == []
    - generic_password_actual.comment == None
    - generic_password_actual.name == test_hostname
    - generic_password_actual.persistence == "Enterprise"
    - generic_password_actual.secret == encoded_pass
    - generic_password_actual.type == "Generic"
    - generic_password_actual.username == "genericuser"

- name: create generic password again
  win_credential:
    name: '{{ test_hostname }}'
    type: generic_password
    persistence: enterprise
    username: genericuser
    secret: genericpass
    state: present
  register: generic_password_again
  vars: *become_vars

- name: assert create generic password again
  assert:
    that:
    - not generic_password_again is changed

- name: fail to create certificate cred with invalid thumbprint
  win_credential:
    name: '{{ test_hostname }}'
    type: domain_certificate
    username: 00112233445566778899AABBCCDDEEFF00112233
    state: present
  register: fail_invalid_cert
  failed_when: fail_invalid_cert.msg != "Failed to find certificate with the thumbprint 00112233445566778899AABBCCDDEEFF00112233 in the CurrentUser\\My store"
  vars: *become_vars

- name: create domain certificate cred (check mode)
  win_credential:
    name: '{{ test_hostname }}'
    type: domain_certificate
    username: '{{ cert_thumbprint }}'
    state: present
  register: domain_cert_check
  check_mode: True
  vars: *become_vars

- name: get result of create domain certificate cred (check mode)
  test_cred_facts:
    name: '{{ test_hostname }}'
    type: domain_certificate
  register: domain_cert_actual_check
  vars: *become_vars

- name: assert create domain certificate cred (check mode)
  assert:
    that:
    - domain_cert_check is changed
    - not domain_cert_actual_check.exists

- name: create domain certificate cred
  win_credential:
    name: '{{ test_hostname }}'
    type: domain_certificate
    username: '{{ cert_thumbprint }}'
    state: present
  register: domain_cert
  vars: *become_vars

- name: get result of create domain certificate cred
  test_cred_facts:
    name: '{{ test_hostname }}'
    type: domain_certificate
  register: domain_cert_actual
  vars: *become_vars

- name: assert create domain certificate cred
  assert:
    that:
    - domain_cert is changed
    - domain_cert_actual.exists
    - domain_cert_actual.alias == None
    - domain_cert_actual.attributes == []
    - domain_cert_actual.comment == None
    - domain_cert_actual.name == test_hostname
    - domain_cert_actual.persistence == "LocalMachine"
    - domain_cert_actual.secret == ""
    - domain_cert_actual.type == "DomainCertificate"
    - domain_cert_actual.username == cert_thumbprint

- name: create domain certificate cred again
  win_credential:
    name: '{{ test_hostname }}'
    type: domain_certificate
    username: '{{ cert_thumbprint }}'
    state: present
  register: domain_cert_again
  vars: *become_vars

- name: assert create domain certificate cred again
  assert:
    that:
    - not domain_cert_again is changed

- name: create generic certificate cred (check mode)
  win_credential:
    name: '{{ test_hostname }}'
    type: generic_certificate
    username: '{{ cert_thumbprint }}'
    secret: '{{ "pin code" | b64encode }}'
    secret_format: base64
    state: present
  register: generic_cert_check
  check_mode: True
  vars: *become_vars

- name: get result of create generic certificate cred (check mode)
  test_cred_facts:
    name: '{{ test_hostname }}'
    type: generic_certificate
  register: generic_cert_actual_check
  vars: *become_vars

- name: assert create generic certificate cred (check mode)
  assert:
    that:
    - generic_cert_check is changed
    - not generic_cert_actual_check.exists

- name: create generic certificate cred
  win_credential:
    name: '{{ test_hostname }}'
    type: generic_certificate
    username: '{{ cert_thumbprint }}'
    secret: '{{ "pin code" | b64encode }}'
    secret_format: base64
    state: present
  register: generic_cert
  vars: *become_vars

- name: get result of create generic certificate cred
  test_cred_facts:
    name: '{{ test_hostname }}'
    type: generic_certificate
  register: generic_cert_actual
  vars: *become_vars

- name: assert create generic certificate cred
  assert:
    that:
    - generic_cert is changed
    - generic_cert_actual.exists
    - generic_cert_actual.alias == None
    - generic_cert_actual.attributes == []
    - generic_cert_actual.comment == None
    - generic_cert_actual.name == test_hostname
    - generic_cert_actual.persistence == "LocalMachine"
    - generic_cert_actual.secret == "pin code" | b64encode
    - generic_cert_actual.type == "GenericCertificate"
    - generic_cert_actual.username == cert_thumbprint

- name: create generic certificate cred again
  win_credential:
    name: '{{ test_hostname }}'
    type: generic_certificate
    username: '{{ cert_thumbprint }}'
    state: present
  register: generic_cert_again
  vars: *become_vars

- name: assert create generic certificate cred again
  assert:
    that:
    - not generic_cert_again is changed
