mirror of
https://github.com/ansible-collections/community.crypto.git
synced 2026-03-27 05:43:22 +00:00
* Add leading underscore. Remove deprecated module utils. * Document module and plugin utils as private. Add changelog fragment. * Convert relative to absolute imports. * Remove unnecessary imports.
215 lines
6.1 KiB
Python
215 lines
6.1 KiB
Python
# 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
|
|
|
|
from __future__ import annotations
|
|
|
|
import typing as t
|
|
from unittest.mock import (
|
|
MagicMock,
|
|
)
|
|
|
|
import pytest
|
|
from ansible_collections.community.crypto.plugins.module_utils._acme.challenges import (
|
|
Authorization,
|
|
Challenge,
|
|
combine_identifier,
|
|
split_identifier,
|
|
)
|
|
from ansible_collections.community.crypto.plugins.module_utils._acme.errors import (
|
|
ACMEProtocolException,
|
|
ModuleFailException,
|
|
)
|
|
|
|
|
|
def test_combine_identifier() -> None:
|
|
assert combine_identifier("", "") == ":"
|
|
assert combine_identifier("a", "b") == "a:b"
|
|
|
|
|
|
def test_split_identifier() -> None:
|
|
assert split_identifier(":") == ("", "")
|
|
assert split_identifier("a:b") == ("a", "b")
|
|
assert split_identifier("a:b:c") == ("a", "b:c")
|
|
with pytest.raises(ModuleFailException) as exc:
|
|
split_identifier("a")
|
|
assert exc.value.msg == 'Identifier "a" is not of the form <type>:<identifier>'
|
|
|
|
|
|
def test_challenge_from_to_json() -> None:
|
|
client = MagicMock()
|
|
|
|
data = {
|
|
"url": "xxx",
|
|
"type": "type",
|
|
"status": "valid",
|
|
}
|
|
client.version = 2
|
|
challenge = Challenge.from_json(client, data)
|
|
assert challenge.data == data
|
|
assert challenge.type == "type"
|
|
assert challenge.url == "xxx"
|
|
assert challenge.status == "valid"
|
|
assert challenge.token is None
|
|
assert challenge.to_json() == data
|
|
|
|
data = {
|
|
"type": "type",
|
|
"status": "valid",
|
|
"token": "foo",
|
|
}
|
|
challenge = Challenge.from_json(None, data, url="xxx") # type: ignore
|
|
assert challenge.data == data
|
|
assert challenge.type == "type"
|
|
assert challenge.url == "xxx"
|
|
assert challenge.status == "valid"
|
|
assert challenge.token == "foo"
|
|
assert challenge.to_json() == data
|
|
|
|
|
|
def test_authorization_from_to_json() -> None:
|
|
client = MagicMock()
|
|
client.version = 2
|
|
|
|
data: dict[str, t.Any]
|
|
|
|
data = {
|
|
"challenges": [],
|
|
"status": "valid",
|
|
"identifier": {
|
|
"type": "dns",
|
|
"value": "example.com",
|
|
},
|
|
}
|
|
authz = Authorization.from_json(client, data, "xxx")
|
|
assert authz.url == "xxx"
|
|
assert authz.status == "valid"
|
|
assert authz.identifier == "example.com"
|
|
assert authz.identifier_type == "dns"
|
|
assert authz.challenges == []
|
|
assert authz.to_json() == {
|
|
"uri": "xxx",
|
|
"challenges": [],
|
|
"status": "valid",
|
|
"identifier": {
|
|
"type": "dns",
|
|
"value": "example.com",
|
|
},
|
|
}
|
|
|
|
data = {
|
|
"challenges": [
|
|
{
|
|
"url": "xxxyyy",
|
|
"type": "type",
|
|
"status": "valid",
|
|
}
|
|
],
|
|
"status": "valid",
|
|
"identifier": {
|
|
"type": "dns",
|
|
"value": "example.com",
|
|
},
|
|
"wildcard": True,
|
|
}
|
|
authz = Authorization.from_json(client, data, "xxx")
|
|
assert authz.url == "xxx"
|
|
assert authz.status == "valid"
|
|
assert authz.identifier == "*.example.com"
|
|
assert authz.identifier_type == "dns"
|
|
assert len(authz.challenges) == 1
|
|
assert authz.challenges[0].data == {
|
|
"url": "xxxyyy",
|
|
"type": "type",
|
|
"status": "valid",
|
|
}
|
|
assert authz.to_json() == {
|
|
"uri": "xxx",
|
|
"challenges": [
|
|
{
|
|
"url": "xxxyyy",
|
|
"type": "type",
|
|
"status": "valid",
|
|
}
|
|
],
|
|
"status": "valid",
|
|
"identifier": {
|
|
"type": "dns",
|
|
"value": "example.com",
|
|
},
|
|
"wildcard": True,
|
|
}
|
|
|
|
|
|
def test_authorization_create_error() -> None:
|
|
client = MagicMock()
|
|
client.version = 2
|
|
client.directory.directory = {}
|
|
with pytest.raises(ACMEProtocolException) as exc:
|
|
Authorization.create(client, "dns", "example.com")
|
|
|
|
assert exc.value.msg == "ACME endpoint does not support pre-authorization."
|
|
|
|
|
|
def test_wait_for_validation_error() -> None:
|
|
client = MagicMock()
|
|
client.version = 2
|
|
data = {
|
|
"challenges": [
|
|
{
|
|
"url": "xxxyyy1",
|
|
"type": "dns-01",
|
|
"status": "invalid",
|
|
"error": {
|
|
"type": "dns-failed",
|
|
"subproblems": [
|
|
{
|
|
"type": "subproblem",
|
|
"detail": "example.com DNS-01 validation failed",
|
|
},
|
|
],
|
|
},
|
|
},
|
|
{
|
|
"url": "xxxyyy2",
|
|
"type": "http-01",
|
|
"status": "invalid",
|
|
"error": {
|
|
"type": "http-failed",
|
|
"subproblems": [
|
|
{
|
|
"type": "subproblem",
|
|
"detail": "example.com HTTP-01 validation failed",
|
|
},
|
|
],
|
|
},
|
|
},
|
|
{
|
|
"url": "xxxyyy3",
|
|
"type": "something-else",
|
|
"status": "valid",
|
|
},
|
|
],
|
|
"status": "invalid",
|
|
"identifier": {
|
|
"type": "dns",
|
|
"value": "example.com",
|
|
},
|
|
}
|
|
client.get_request = MagicMock(return_value=(data, {}))
|
|
authz = Authorization.from_json(client, data, "xxx")
|
|
with pytest.raises(ACMEProtocolException) as exc:
|
|
authz.wait_for_validation(client, "dns")
|
|
|
|
assert exc.value.msg == (
|
|
'Failed to validate challenge for dns:example.com: Status is "invalid". Challenge dns-01: Error dns-failed Subproblems:\n'
|
|
'(dns-01.0) Error subproblem: "example.com DNS-01 validation failed"; Challenge http-01: Error http-failed Subproblems:\n'
|
|
'(http-01.0) Error subproblem: "example.com HTTP-01 validation failed".'
|
|
)
|
|
data = data.copy()
|
|
data["uri"] = "xxx"
|
|
assert exc.value.module_fail_args == {
|
|
"identifier": "dns:example.com",
|
|
"authorization": data,
|
|
}
|