---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

####################################################################
# WARNING: These are designed specifically for Ansible tests       #
# and should not be used as examples of how to write Ansible roles #
####################################################################

- set_fact:
    new_signing_key: "{{ remote_tmp_dir }}/new_key"
    new_public_key: "{{ remote_tmp_dir }}/new_key.pub"

- name: Generate new test key
  openssh_keypair:
    path: "{{ new_signing_key }}"

- name: Generate cert with original keys
  openssh_cert:
    type: user
    path: "{{ certificate_path }}"
    public_key: "{{ public_key }}"
    signing_key: "{{ signing_key }}"
    valid_from: always
    valid_to: forever

- block:
    - name: Generate cert with updated signature algorithm
      openssh_cert:
        type: user
        path: "{{ certificate_path }}"
        public_key: "{{ public_key }}"
        signing_key: "{{ signing_key }}"
        signature_algorithm: rsa-sha2-256
        valid_from: always
        valid_to: forever
      register: updated_signature_algorithm

    - name: Assert signature algorithm update causes change
      assert:
        that:
          - updated_signature_algorithm is changed

    - name: Generate cert with updated signature algorithm (idempotent)
      openssh_cert:
        type: user
        path: "{{ certificate_path }}"
        public_key: "{{ public_key }}"
        signing_key: "{{ signing_key }}"
        signature_algorithm: rsa-sha2-256
        valid_from: always
        valid_to: forever
      register: updated_signature_algorithm_idempotent

    - name: Assert signature algorithm update is idempotent
      assert:
        that:
          - updated_signature_algorithm_idempotent is not changed

    - block:
      - name: Generate cert with original signature algorithm
        openssh_cert:
          type: user
          path: "{{ certificate_path }}"
          public_key: "{{ public_key }}"
          signing_key: "{{ signing_key }}"
          signature_algorithm: ssh-rsa
          valid_from: always
          valid_to: forever
        register: second_signature_algorithm

      - name: Assert second signature algorithm update causes change
        assert:
          that:
            - second_signature_algorithm is changed
      # RHEL9 and Fedora 41 disable the SHA-1 algorithms by default, making this test fail with a 'libcrypt' error.
      # Other systems which impose a similar restriction may also need to skip this block in the future.
      when:
        - not (ansible_facts['distribution'] == "RedHat" and (ansible_facts['distribution_major_version'] | int) >= 9)
        - not (ansible_facts['distribution'] == "Fedora" and (ansible_facts['distribution_major_version'] | int) >= 41)

    - name: Omit signature algorithm
      openssh_cert:
        type: user
        path: "{{ certificate_path }}"
        public_key: "{{ public_key }}"
        signing_key: "{{ signing_key }}"
        valid_from: always
        valid_to: forever
      register: omitted_signature_algorithm

    - name: Assert omitted_signature_algorithm does not cause change
      assert:
        that:
          - omitted_signature_algorithm is not changed

    - name: Revert to original certificate
      openssh_cert:
        type: user
        path: "{{ certificate_path }}"
        public_key: "{{ public_key }}"
        signing_key: "{{ signing_key }}"
        valid_from: always
        valid_to: forever
        regenerate: always
  when: openssh_version is version("7.3", ">=")

- name: Generate cert with new signing key
  openssh_cert:
    type: user
    path: "{{ certificate_path }}"
    public_key: "{{ public_key }}"
    signing_key: "{{ new_signing_key }}"
    valid_from: always
    valid_to: forever
  register: new_signing_key_output

- name: Generate cert with new public key
  openssh_cert:
    type: user
    path: "{{ certificate_path }}"
    public_key: "{{ new_public_key }}"
    signing_key: "{{ signing_key }}"
    valid_from: always
    valid_to: forever
  register: new_public_key_output

- name: Generate cert with new signing key - full idempotency
  openssh_cert:
    type: user
    path: "{{ certificate_path }}"
    public_key: "{{ public_key }}"
    signing_key: "{{ new_signing_key }}"
    valid_from: always
    valid_to: forever
    regenerate: full_idempotence
  register: new_signing_key_full_idempotency_output

- name: Generate cert with new pubic key - full idempotency
  openssh_cert:
    type: user
    path: "{{ certificate_path }}"
    public_key: "{{ new_public_key }}"
    signing_key: "{{ new_signing_key }}"
    valid_from: always
    valid_to: forever
    regenerate: full_idempotence
  register: new_public_key_full_idempotency_output

- name: Assert changes to public key or signing key results in no change unless idempotency=full
  assert:
    that:
      - new_signing_key_output is not changed
      - new_public_key_output is not changed
      - new_signing_key_full_idempotency_output is changed
      - new_public_key_full_idempotency_output is changed

- name: Remove certificate
  openssh_cert:
    path: "{{ certificate_path }}"
    state: absent

- name: Remove new keypair
  openssh_keypair:
    path: "{{ new_signing_key }}"
    state: absent
