File: test_utils.py

package info (click to toggle)
python-argon2 25.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 360 kB
  • sloc: python: 1,251; makefile: 156
file content (145 lines) | stat: -rw-r--r-- 3,654 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# SPDX-License-Identifier: MIT

from base64 import b64encode
from dataclasses import replace

import pytest

from hypothesis import given
from hypothesis import strategies as st

from argon2 import Parameters, Type, extract_parameters
from argon2._utils import NoneType, _check_types, _decoded_str_len
from argon2.exceptions import InvalidHashError


class TestCheckTypes:
    def test_success(self):
        """
        Returns None if all types are okay.
        """
        assert None is _check_types(
            bytes=(b"bytes", bytes),
            tuple=((1, 2), tuple),
            str_or_None=(None, (str, NoneType)),
        )

    def test_fail(self):
        """
        Returns summary of failures.
        """
        rv = _check_types(
            bytes=("not bytes", bytes), str_or_None=(42, (str, NoneType))
        )

        assert "." == rv[-1]  # proper grammar FTW
        assert "'str_or_None' must be a str, or NoneType (got int)" in rv

        assert "'bytes' must be a bytes (got str)" in rv


@given(st.binary())
def test_decoded_str_len(bs):
    """
    _decoded_str_len computes the resulting length.
    """
    assert len(bs) == _decoded_str_len(len(b64encode(bs).rstrip(b"=")))


VALID_HASH = (
    "$argon2id$v=19$m=65536,t=2,p=4$"
    "c29tZXNhbHQ$GpZ3sK/oH9p7VIiV56G/64Zo/8GaUw434IimaPqxwCo"
)
VALID_PARAMETERS = Parameters(
    type=Type.ID,
    salt_len=8,
    hash_len=32,
    version=19,
    memory_cost=65536,
    time_cost=2,
    parallelism=4,
)

VALID_HASH_V18 = (
    "$argon2i$m=8,t=1,p=1$c29tZXNhbHQ$gwQOXSNhxiOxPOA0+PY10P9QFO"
    "4NAYysnqRt1GSQLE55m+2GYDt9FEjPMHhP2Cuf0nOEXXMocVrsJAtNSsKyfg"
)
VALID_PARAMETERS_V18 = Parameters(
    type=Type.I,
    salt_len=8,
    hash_len=64,
    version=18,
    memory_cost=8,
    time_cost=1,
    parallelism=1,
)


class TestExtractParameters:
    def test_valid_hash(self):
        """
        A valid hash is parsed.
        """
        parsed = extract_parameters(VALID_HASH)

        assert VALID_PARAMETERS == parsed

    def test_valid_hash_v18(self):
        """
        A valid Argon v1.2 hash is parsed.
        """

        parsed = extract_parameters(VALID_HASH_V18)

        assert VALID_PARAMETERS_V18 == parsed

    @pytest.mark.parametrize(
        "hash",
        [
            "",
            "abc" + VALID_HASH,
            VALID_HASH.replace("p=4", "p=four"),
            VALID_HASH.replace(",p=4", ""),
        ],
    )
    def test_invalid_hash(self, hash):
        """
        Invalid hashes of various types raise an InvalidHash error.
        """
        with pytest.raises(InvalidHashError):
            extract_parameters(hash)


class TestParameters:
    def test_eq(self):
        """
        Parameters are equal iff every attribute is equal.
        """
        assert VALID_PARAMETERS == VALID_PARAMETERS  # noqa: PLR0124
        assert VALID_PARAMETERS != replace(VALID_PARAMETERS, salt_len=9)

    def test_eq_wrong_type(self):
        """
        Parameters are only compared if they have the same type.
        """
        assert VALID_PARAMETERS != "foo"
        assert VALID_PARAMETERS != object()

    def test_repr(self):
        """
        __repr__ returns s ensible string.
        """
        assert repr(
            Parameters(
                type=Type.ID,
                salt_len=8,
                hash_len=32,
                version=19,
                memory_cost=65536,
                time_cost=2,
                parallelism=4,
            )
        ) == (
            "Parameters(type=<Type.ID: 2>, version=19, salt_len=8, "
            "hash_len=32, time_cost=2, memory_cost=65536, parallelism=4)"
        )