Skip to content

Commit

Permalink
move view tests to pytest
Browse files Browse the repository at this point in the history
  • Loading branch information
mathiasertl committed Nov 28, 2024
1 parent 35bc4da commit 76323eb
Show file tree
Hide file tree
Showing 15 changed files with 926 additions and 864 deletions.
40 changes: 21 additions & 19 deletions ca/django_ca/key_backends/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,25 +77,25 @@ def validate_key_size(self) -> "typing.Self":


class KeyBackendBase:
"""Base class for backend classes to create private keys (CAs or OCSP delegate responder certificates)."""
"""Base class for backends that create private keys (CAs or OCSP delegate responder certificates)."""

#: Alias under which this backend is configured under settings.KEY_BACKENDS.
alias: str

#: Private key types supported by the key backend. This defines the choices for the ``--key-type``
#: argument and the `key_type` parameter in
#: :py:func:`~django_ca.key_backends.base.KeyBackend.get_create_private_key_options` is guaranteed to be
#: :py:func:`~django_ca.key_backends.KeyBackend.get_create_private_key_options` is guaranteed to be
#: one of the named values.
supported_key_types: tuple[str, ...]

#: Hash algorithms supported by the key backend. This defines the choices for the ``--algorithm`` argument
#: and the `algorithm` argument in :py:func:`~django_ca.key_backends.base.KeyBackend.sign_certificate` is
#: and the `algorithm` argument in :py:func:`~django_ca.key_backends.KeyBackend.sign_certificate` is
#: guaranteed to be one of the named values.
supported_hash_algorithms: tuple[HashAlgorithms, ...] = tuple(constants.HASH_ALGORITHM_TYPES)

#: Elliptic curves supported by this backend for elliptic curve keys. This defines the choices for the
#: ``--elliptic-curve`` parameter and the `elliptic_curve` parameter in
#: :py:func:`~django_ca.key_backends.base.KeyBackend.get_create_private_key_options` is guaranteed to be
#: :py:func:`~django_ca.key_backends.KeyBackend.get_create_private_key_options` is guaranteed to be
#: one of the named values if ``--key-type=EC`` is passed.
supported_elliptic_curves: tuple[str, ...]

Expand Down Expand Up @@ -144,9 +144,9 @@ def add_create_private_key_group(self, parser: CommandParser) -> Optional[Argume
"""Add an argument group for arguments for private key generation with this backend.
By default, the title and description of the argument group is based on
:py:attr:`~django_ca.key_backends.base.KeyBackend.alias`,
:py:attr:`~django_ca.key_backends.base.KeyBackend.title` and
:py:attr:`~django_ca.key_backends.base.KeyBackend.description`.
:py:attr:`~django_ca.key_backends.base.KeyBackendBase.alias`,
:py:attr:`~django_ca.key_backends.KeyBackend.title` and
:py:attr:`~django_ca.key_backends.KeyBackend.description`.
Return ``None`` if you don't need to create such a group.
"""
Expand All @@ -159,16 +159,16 @@ def add_store_private_key_group(self, parser: CommandParser) -> Optional[Argumen
"""Add an argument group for storing private keys (when importing an existing CA).
By default, this method adds the same group as
:py:func:`~django_ca.key_backends.base.KeyBackend.add_create_private_key_group`
:py:func:`~django_ca.key_backends.KeyBackend.add_create_private_key_group`
"""
return self.add_create_private_key_group(parser)

def add_use_private_key_group(self, parser: CommandParser) -> Optional[ArgumentGroup]:
"""Add an argument group for arguments required for using a private key stored with this backend.
By default, the title and description of the argument group is based on
:py:attr:`~django_ca.key_backends.base.KeyBackend.alias` and
:py:attr:`~django_ca.key_backends.base.KeyBackend.title`.
:py:attr:`~django_ca.key_backends.base.KeyBackendBase.alias` and
:py:attr:`~django_ca.key_backends.KeyBackend.title`.
Return ``None`` if you don't need to create such a group.
"""
Expand All @@ -183,15 +183,15 @@ def add_create_private_key_arguments(self, group: ArgumentGroup) -> None:
Add arguments that can be used for generating private keys with your backend to `group`. The arguments
you add here are expected to be loaded (and validated) using
:py:func:`~django_ca.key_backends.base.KeyBackend.get_create_private_key_options`.
:py:func:`~django_ca.key_backends.KeyBackend.get_create_private_key_options`.
"""

@abc.abstractmethod
def add_use_parent_private_key_arguments(self, group: ArgumentGroup) -> None:
"""Add arguments for loading the private key of a parent certificate authority.
The arguments you add here are expected to be loaded (and validated) using
:py:func:`~django_ca.key_backends.base.KeyBackend.get_use_parent_private_key_options`.
:py:func:`~django_ca.key_backends.KeyBackend.get_use_parent_private_key_options`.
"""

@abc.abstractmethod
Expand All @@ -203,7 +203,7 @@ def add_use_private_key_arguments(self, group: ArgumentGroup) -> None:
"""Add arguments required for using private key stored with this backend.
The arguments you add here are expected to be loaded (and validated) using
:py:func:`~django_ca.key_backends.base.KeyBackend.get_use_parent_private_key_options`.
:py:func:`~django_ca.key_backends.KeyBackend.get_use_parent_private_key_options`.
"""
return None

Expand All @@ -219,7 +219,7 @@ def get_create_private_key_options(
`options` is the dictionary of arguments from :command:`manage.py init_ca` (including default values).
The returned model will be passed to
:py:func:`~django_ca.key_backends.base.KeyBackend.create_private_key`.
:py:func:`~django_ca.key_backends.KeyBackend.create_private_key`.
"""

@abc.abstractmethod
Expand Down Expand Up @@ -262,7 +262,7 @@ def is_usable(
"""Boolean returning if the given `ca` can be used to sign new certificates (or CRLs).
The `options` are the options returned by
:py:func:`~django_ca.key_backends.base.KeyBackend.get_use_private_key_options`. It may be ``None`` in
:py:func:`~django_ca.key_backends.KeyBackend.get_use_private_key_options`. It may be ``None`` in
cases where key options cannot (yet) be loaded. If ``None``, the backend should return ``False`` if it
knows for sure that it will not be usable, and ``True`` if usability cannot be determined.
"""
Expand All @@ -274,7 +274,7 @@ def check_usable(
"""Check if the given CA is usable, raise ValueError if not.
The `options` are the options returned by
:py:func:`~django_ca.key_backends.base.KeyBackend.get_use_private_key_options`. It may be ``None`` in
:py:func:`~django_ca.key_backends.KeyBackend.get_use_private_key_options`. It may be ``None`` in
cases where key options cannot (yet) be loaded. If ``None``, the backend should return ``False`` if it
knows for sure that it will not be usable, and ``True`` if usability cannot be determined.
"""
Expand Down Expand Up @@ -394,8 +394,8 @@ def get_csr_algorithm(self, key_type: ParsableKeyType) -> Optional[AllowedHashTy
"""Helper function to get a usable signing algorithm for the given key type.
This function can be used to get a default signing algorithm when creating a CSR in
:func:`~django_ca.key_backends.OCSPKeyBackend.create_private_key`. You are not obliged to use this
function, it is here merely for convenience.
:py:func:`~django_ca.key_backends.OCSPKeyBackend.create_private_key`. You are not obliged to use
this function, it is here merely for convenience.
"""
if key_type in ("Ed25519", "Ed448"):
return None
Expand Down Expand Up @@ -459,13 +459,15 @@ def load_private_key_data(self, ca: "CertificateAuthority") -> bytes:
"""Load the raw private key as bytes. Both PEM and DER representations are supported."""

# COVERAGE NOTE: Function is implemented in all subclasses.`
# pylint: disable-next=unused-argument
def get_private_key_password(self, ca: "CertificateAuthority") -> Optional[bytes]: # pragma: no cover
"""Get the private key password. The default implementation never returns a password."""
return None

def load_private_key(self, ca: "CertificateAuthority") -> CertificateIssuerPrivateKeyTypes:
"""Function to load the private key and return the raw private key."""
raw_private_key = self.load_private_key_data(ca)
password = self.get_private_key_password(ca)
password = self.get_private_key_password(ca) # pylint: disable=assignment-from-none

try:
loaded_key = serialization.load_der_private_key(raw_private_key, password)
Expand Down
2 changes: 1 addition & 1 deletion ca/django_ca/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -807,7 +807,7 @@ def sign(
return signed_cert

@deprecate_argument("expires", RemovedInDjangoCA230Warning, replacement="not_after")
def generate_ocsp_key( # pylint: disable=too-many-locals
def generate_ocsp_key(
self,
key_backend_options: BaseModel,
key_type: Optional[ParsableKeyType] = None,
Expand Down
1 change: 1 addition & 0 deletions ca/django_ca/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"django_ca.tests.acme.views.assertions",
"django_ca.tests.admin.assertions",
"django_ca.tests.pydantic.base",
"django_ca.tests.views.assertions",
)


Expand Down
2 changes: 1 addition & 1 deletion ca/django_ca/tests/base/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,6 @@ def usable_cert(request: "SubRequest") -> Certificate:


@pytest.fixture(scope="session")
def x448_private_key():
def x448_private_key() -> X448PrivateKey:
"""Session fixture for an x448 private key."""
return X448PrivateKey.generate()
1 change: 0 additions & 1 deletion ca/django_ca/tests/commands/test_regenerate_ocsp_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ def assertKey( # pylint: disable=invalid-name
ca: CertificateAuthority,
key_type: Optional[type[CertificateIssuerPrivateKeyTypes]] = None,
key_size: Optional[int] = 2048,
password: Optional[bytes] = None,
excludes: Optional[Iterable[int]] = None,
elliptic_curve: type[ec.EllipticCurve] = ec.SECP256R1,
) -> tuple[CertificateIssuerPrivateKeyTypes, x509.Certificate]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def test_unsupported_private_key(x448_private_key: X448PrivateKey, root: Certifi
root.save()

with pytest.raises(ValueError, match=r"Unsupported private key type\.$"):
root.ocsp_key_backend.load_private_key(root)
root.ocsp_key_backend.load_private_key(root) # type: ignore[attr-defined]


def test_get_default_key_size(ec: CertificateAuthority) -> None:
Expand Down
2 changes: 1 addition & 1 deletion ca/django_ca/tests/key_backends/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def test_key_backends_class_is_not_key_backend(settings: SettingsWrapper) -> Non
key_backends[model_settings.CA_DEFAULT_KEY_BACKEND]


def test_key_backend_overwritten_methods(settings: SettingsWrapper, root: CertificateAuthority) -> None:
def test_key_backend_overwritten_methods(settings: SettingsWrapper) -> None:
"""Test methods usually overwritten by StoragesBackend."""
settings.CA_KEY_BACKENDS = {
model_settings.CA_DEFAULT_KEY_BACKEND: {
Expand Down
Loading

0 comments on commit 76323eb

Please sign in to comment.