From f83ce44d97e1c3fe5b4b7515e07bf88f496637d1 Mon Sep 17 00:00:00 2001 From: Paulo Amaral Date: Mon, 6 Nov 2023 16:46:49 +0000 Subject: [PATCH 1/3] Update Pydantic to version 2.4.2 --- csp/models.py | 38 ++++++++++++++++++-------------------- pyproject.toml | 2 +- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/csp/models.py b/csp/models.py index 87d11ac..53a31b9 100644 --- a/csp/models.py +++ b/csp/models.py @@ -2,21 +2,19 @@ import logging from collections import defaultdict -from typing import Any, TypeAlias +from typing import Any from django.db import models from django.db.models import F from django.db.utils import IntegrityError from django.utils.timezone import now as tz_now -from pydantic import BaseModel, Field, root_validator, validator +from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator from .settings import PolicyType from .utils import strip_query logger = logging.getLogger(__name__) -PydanticValues: TypeAlias = dict[str, str | None] - class ReportData(BaseModel): # browser support for CSP reports turns out to be patchy at best - @@ -28,17 +26,18 @@ class ReportData(BaseModel): # min_length ensures we don't have an empty string blocked_uri: str = Field(alias="blocked-uri", min_length=1) # we must have one of these - validate_directives enforces this - effective_directive: str | None = Field(alias="effective-directive") - violated_directive: str | None = Field(alias="violated-directive") + effective_directive: str | None = Field(None, alias="effective-directive") + violated_directive: str | None = Field(None, alias="violated-directive") # optional disposition: str | None = Field("", alias="disposition") document_uri: str | None = Field("", alias="document-uri") - original_policy: str | None = Field(alias="original-policy") - referrer: str | None = Field(alias="referrer") - script_sample: str | None = Field(alias="script-sample") + original_policy: str | None = Field(None, alias="original-policy") + referrer: str | None = Field(None, alias="referrer") + script_sample: str | None = Field(None, alias="script-sample") status_code: str | None = Field(0, alias="status-code") - @validator("document_uri", "blocked_uri") + @field_validator("document_uri", "blocked_uri") + @classmethod def strip_uri(cls, uri: str) -> str: """ Strip querystring and truncate to fit model length. @@ -49,25 +48,24 @@ def strip_uri(cls, uri: str) -> str: """ return strip_query(uri)[:200] if uri else "" - @root_validator - def validate_directives(cls, values: PydanticValues) -> PydanticValues: + @model_validator(mode="after") + def validate_directives(self) -> ReportData: """Ensure that we have either effective_directive or violated_directive.""" - if values.get("effective_directive", ""): - return values + if self.effective_directive: + return self # if effective_directive is empty, but violated_directive is not, - # then udpate the former with the latter. - if violated_directive := values.get("violated_directive", ""): + # then update the former with the latter. + if self.violated_directive: logger.debug( "'effective_directive' missing - using 'violated_directive' attr." ) - values["effective_directive"] = violated_directive - return values + self.effective_directive = self.violated_directive + return self raise ValueError( "Either 'effective_directive' or 'violated_directive' must be present." ) - class Config: - allow_population_by_field_name = True + model_config = ConfigDict(populate_by_name=True, coerce_numbers_to_str=True) class DispositionChoices(models.TextChoices): diff --git a/pyproject.toml b/pyproject.toml index 6eb5fbc..ea9d948 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ packages = [{ include = "csp" }] [tool.poetry.dependencies] python = "^3.8" django = "^3.2 || ^4.0" -pydantic = "^1" +pydantic = "*" [tool.poetry.dev-dependencies] black = "*" From 56fdca52ed574865af1eb620a6b3528a8b5c8377 Mon Sep 17 00:00:00 2001 From: Paulo Amaral Date: Mon, 6 Nov 2023 17:20:58 +0000 Subject: [PATCH 2/3] Drop support for Python < 3.10 and update CHANGELOG --- CHANGELOG | 5 +++++ pyproject.toml | 4 +--- tox.ini | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 36fecdf..6360aa2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +## [3.0.0] - 2023-02-17 + +- Drop support for Python < 3.10 +- Drop support for Pydantic < 2 + ## [0.10.0] - 2023-02-17 - Improve admin list view to include date filters and value search [#8] diff --git a/pyproject.toml b/pyproject.toml index ea9d948..4475e8b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "django-csp-plus" -version = "0.10.0" +version = "3.0.0" description = "CSP tracking and violation report endpoint." license = "MIT" authors = ["YunoJuno "] @@ -19,8 +19,6 @@ classifiers = [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", ] diff --git a/tox.ini b/tox.ini index f032acb..94b0745 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] isolated_build = True -envlist = fmt, lint, mypy, checks, py{3.8,3.9,3.10,3.11}-django{32,41,42,main} +envlist = fmt, lint, mypy, checks, py{3.10,3.11}-django{32,41,42,main} [testenv] deps = From 13d70c4532751339fd78901bdf5f7cdf63f0aa73 Mon Sep 17 00:00:00 2001 From: Paulo Amaral Date: Tue, 7 Nov 2023 10:06:37 +0000 Subject: [PATCH 3/3] Update Python and Django versions for local runs and CI --- .github/workflows/tox.yml | 11 +++++++++-- tox.ini | 6 +++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index c4ac2ca..d722455 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -37,8 +37,15 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python: ["3.10"] - django: [32,40,41,main] + python: ["3.10", "3.11", "3.12"] + django: [32,42,50,main] + exclude: + - python: "3.11" + django: "32" + - python: "3.12" + django: "32" + - python: "3.12" + django: "42" env: TOXENV: py${{ matrix.python }}-django${{ matrix.django }} diff --git a/tox.ini b/tox.ini index 94b0745..d72a37d 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,10 @@ [tox] isolated_build = True -envlist = fmt, lint, mypy, checks, py{3.10,3.11}-django{32,41,42,main} +envlist = + fmt, lint, mypy, checks, + py{3.10}-django{32,42,50,main} + py{3.11}-django{42,50,main} + py{3.12}-django{50,main} [testenv] deps =