Skip to content

Commit

Permalink
drop support for deprecated software versions
Browse files Browse the repository at this point in the history
  • Loading branch information
mathiasertl committed Dec 26, 2024
1 parent ac4ca2f commit 9dd2e0d
Show file tree
Hide file tree
Showing 9 changed files with 24 additions and 83 deletions.
8 changes: 3 additions & 5 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@ jobs:
matrix:
os: [ ubuntu-latest ]
python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13" ]
django-version: [ "4.2.0", "5.0.0", "5.1.0" ]
cryptography-version: [ "43.0", "44.0" ]
pydantic-version: [ "2.9.0", "2.10.0" ]
django-version: [ "4.2.0", "5.1.0" ]
cryptography-version: [ "44.0" ]
pydantic-version: [ "2.10.0" ]
exclude:
- python-version: 3.9
django-version: 5.0.0
- python-version: 3.9
django-version: 5.1.0

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Documentation is available at https://django-ca.readthedocs.org/.
4. Private key storage on the file system, in the database or in a Hardware Security Module (HSM).
5. Management via command line and/or via Django's admin interface.
6. Get email notifications about certificates about to expire.
7. Written in Python 3.9+, Django 4.2+ and cryptography 43+.
7. Written in Python 3.9+, Django 4.2+ and cryptography 44+.

Please see https://django-ca.readthedocs.org for more extensive documentation.

Expand Down
4 changes: 2 additions & 2 deletions ca/django_ca/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ class Media: # pylint: disable=missing-class-docstring
class CertificateAuthorityAdmin(CertificateMixin[CertificateAuthority], CertificateAuthorityAdminBase):
"""ModelAdmin for :py:class:`~django_ca.models.CertificateAuthority`."""

if django.VERSION >= (5, 0): # pragma: django>=5.0 branch
if django.VERSION >= (5, 0): # pragma: django>=5.1 branch
formfield_overrides = {models.URLField: {"assume_scheme": "https"}}

fieldsets = (
Expand Down Expand Up @@ -1151,7 +1151,7 @@ def queryset(self, request: HttpRequest, queryset: QuerySetTypeVar) -> QuerySetT
class AcmeAccountAdmin(AcmeAccountAdminBase):
"""ModelAdmin class for :py:class:`~django_ca.models.AcmeAccount`."""

if django.VERSION >= (5, 0): # pragma: django>=5.0 branch
if django.VERSION >= (5, 0): # pragma: django>=5.1 branch
formfield_overrides = {models.URLField: {"assume_scheme": "https"}}

list_display = ("first_contact", "ca", "slug", "status", "created", "terms_of_service_agreed")
Expand Down
61 changes: 1 addition & 60 deletions ca/django_ca/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from collections.abc import Iterable
from datetime import timedelta
from importlib.util import find_spec
from typing import Annotated, Any, Literal, Optional, Union, cast
from typing import Annotated, Any, Literal, Optional, Union

from annotated_types import Ge, Le
from pydantic import (
Expand All @@ -33,7 +33,6 @@
from cryptography import x509
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.x509.oid import NameOID

from django.conf import settings as _settings
from django.core.exceptions import ImproperlyConfigured
Expand Down Expand Up @@ -175,64 +174,6 @@
}


def _check_name(name: x509.Name) -> None:
# WARNING: This function is a duplicate of the function in utils.

multiple_oids = (NameOID.DOMAIN_COMPONENT, NameOID.ORGANIZATIONAL_UNIT_NAME, NameOID.STREET_ADDRESS)

seen = set()

for attr in name:
oid = attr.oid

# Check if any fields are duplicate where this is not allowed (e.g. multiple CommonName fields)
if oid in seen and oid not in multiple_oids:
raise ImproperlyConfigured(
f'{name}: Contains multiple "{constants.NAME_OID_NAMES[attr.oid]}" fields.'
)

value = attr.value
if oid == NameOID.COMMON_NAME and (not value or len(value) > 64): # pragma: only cryptography<43
# Imitate message from cryptography 43
raise ImproperlyConfigured(
f"Value error, Attribute's length must be >= 1 and <= 64, but it was {len(attr.value)}"
)

seen.add(oid)


def _parse_deprecated_name_value(value: Any) -> Optional[x509.Name]:
if not isinstance(value, (list, tuple)):
raise ValueError(f"{value}: Must be a list or tuple.")

name_attributes: list[x509.NameAttribute] = []
for elem in value:
if isinstance(elem, x509.NameAttribute):
name_attributes.append(elem)
elif isinstance(elem, (tuple, list)):
if len(elem) != 2:
raise ImproperlyConfigured(f"{elem}: Must be lists/tuples with two items, got {len(elem)}.")
if not isinstance(elem[1], str):
raise ImproperlyConfigured(f"{elem[1]}: Item values must be strings.")

if isinstance(elem[0], x509.ObjectIdentifier):
name_oid = elem[0]
elif isinstance(elem[0], str):
# name_oid_parser() always returns x509.ObjectedIdentifier for strings
name_oid = cast(x509.ObjectIdentifier, name_oid_parser(elem[0]))
else:
raise ValueError(f"{elem[0]}: Must be a x509.ObjectIdentifier or str.")

name_attribute = x509.NameAttribute(oid=name_oid, value=elem[1])
name_attributes.append(name_attribute)
else:
raise ImproperlyConfigured(f"{elem}: Items must be a x509.NameAttribute, list or tuple.")

normalized_name = x509.Name(name_attributes)
_check_name(normalized_name)
return normalized_name


def _subject_validator(value: Any) -> Any:
return NameModel(value).cryptography

Expand Down
8 changes: 7 additions & 1 deletion docs/source/changelog/TBR_2.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,14 @@ Settings
* Dropped support for the old subject format in :ref:`settings-ca-default-subject` and subjects in profiles
(deprecated since 1.29.0).

************
Dependencies
************

* **BACKWARDS INCOMPATIBLE:** Dropped support for ``django~=5.0.0``.

**********
Python API
**********

* ``django_ca.utils.get_storage()`` was be removed (deprecated since 2.0).
* ``django_ca.utils.get_storage()`` was be removed (deprecated since 2.0).
2 changes: 1 addition & 1 deletion docs/source/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ Features:
#. Private key storage on the file system, in the database or in a Hardware Security Module (HSM).
#. Management via command line and/or via Django's admin interface.
#. Get email notifications about certificates about to expire.
#. Written in Python 3.9+, Django 4.2+ and cryptography 43+.
#. Written in Python 3.9+, Django 4.2+ and cryptography 44+.

Please see https://django-ca.readthedocs.org for the most recent documentation.
1 change: 1 addition & 0 deletions docs/source/quickstart/as_app.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ tested with what release (changes to previous versions in **bold**):
========= ============== ================== =============== ============= ================ ==================
django-ca Python Django cryptography Celery acme pydantic
========= ============== ================== =============== ============= ================ ==================
2.1 3.9 - **3.13** 4.2, 5.1 **43** - **44** 5.4 **2.11** **2.9** - **2.10**
2.1 3.9 - **3.13** 4.2 - 5.1 **43** - **44** 5.4 **2.11** **2.9** - **2.10**
2.0 3.9 - 3.12 4.2 - **5.1** 42 - **43** **5.4** **2.10** - 2.11 **2.7 - 2.9**
1.29 **3.9** - 3.12 4.2 - 5.0 **42** 5.3 - **5.4** **2.9 - 2.11** 2.5 - **2.7**
Expand Down
13 changes: 6 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ build-backend = "setuptools.build_meta"
# https://devguide.python.org/versions/#versions
python = ["3.9", "3.10", "3.11", "3.12", "3.13"]
# https://www.djangoproject.com/download/
django = ["4.2", "5.0", "5.1"]
cryptography = ["43", "44"]
acme = ["2.11", "3.0"]
pydantic = ["2.9", "2.10"]
django = ["4.2", "5.1"]
cryptography = ["44"]
acme = ["3.0"]
pydantic = ["2.10"]

# https://alpinelinux.org/releases/
alpine = [
Expand Down Expand Up @@ -99,7 +99,6 @@ description = "A Django app providing a TLS certificate authority."
classifiers = [
"Development Status :: 5 - Production/Stable",
"Framework :: Django :: 4.2",
"Framework :: Django :: 5.0",
"Framework :: Django :: 5.1",
"Framework :: Django",
"Intended Audience :: Developers",
Expand All @@ -124,9 +123,9 @@ dynamic = ["version", "readme"]
requires-python = ">=3.9"
dependencies = [
"Django>=4.2",
"acme>=2.11",
"acme>=3.0",
"asn1crypto>=1.5",
"cryptography>=43",
"cryptography>=44",
"django-object-actions>=4.0.0",
"dnspython>=2.5",
"idna>=3.4",
Expand Down
8 changes: 2 additions & 6 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[tox]
envlist = pylint,docs,lint,mypy,demo,dist-test
py{310,311,312,313}-dj{5.0,5.1}-cg{43,44}-acme{2.11,3.0}-pydantic{2.9,2.10}
py{39,310,311,312,313}-dj{4.2}-cg{43,44}-acme{2.11,3.0}-pydantic{2.9,2.10}
py{310,311,312,313}-dj{5.1}-cg{44}-acme{3.0}-pydantic{2.10}
py{39,310,311,312,313}-dj{4.2}-cg{44}-acme{3.0}-pydantic{2.10}
faketime

[testenv]
Expand All @@ -10,13 +10,9 @@ deps =
-r requirements.txt
-r requirements/requirements-test.txt
dj4.2: Django~=4.2.0
dj5.0: Django~=5.0.0
dj5.1: Django~=5.1.0
cg43: cryptography~=43.0
cg44: cryptography~=44.0
acme2.11: acme~=2.11.0
acme3.0: acme~=3.0.0
pydantic2.9: pydantic~=2.9.0
pydantic2.10: pydantic~=2.10.0
setenv =
COVERAGE_FILE = {envdir}/.coverage
Expand Down

0 comments on commit 9dd2e0d

Please sign in to comment.