Skip to content

Commit

Permalink
Maintenance update
Browse files Browse the repository at this point in the history
  • Loading branch information
MrThearMan committed Oct 28, 2023
1 parent 6bb0116 commit f9b57a0
Show file tree
Hide file tree
Showing 27 changed files with 823 additions and 639 deletions.
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ body:
description: >-
Please note that python versions not available below are not supported.
options:
- "3.12"
- "3.11"
- "3.10"
- "3.9"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ jobs:
test:
uses: MrThearMan/CI/.github/workflows/[email protected]
with:
python-version: '["3.8", "3.9", "3.10", "3.11"]'
python-version: '["3.8", "3.9", "3.10", "3.11", "3.12"]'
exclude: '[{"os": "windows-latest", "python-version": "3.8"}]'
10 changes: 3 additions & 7 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
repos:

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.5.0
hooks:
- id: check-toml
- id: check-yaml
Expand All @@ -15,11 +15,7 @@ repos:
]

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.0.278
rev: v0.1.3
hooks:
- id: ruff

- repo: https://github.com/psf/black
rev: 23.7.0
hooks:
- id: black
- id: ruff-format
15 changes: 5 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export DJANGO_SETTINGS_MODULE = tests.django.settings
export DJANGO_SETTINGS_MODULE = tests.project.settings

.PHONY: help
.PHONY: dev
Expand All @@ -7,8 +7,7 @@ export DJANGO_SETTINGS_MODULE = tests.django.settings
.PHONY: test
.PHONY: tox
.PHONY: hook
.PHONY: pre-commit
.PHONY: pre-commit-update
.PHONY: lint
.PHONY: mypy
.PHONY: Makefile

Expand All @@ -30,8 +29,7 @@ define helptext
test <name> Run all tests maching the given <name>
tox <args> Run all tests with tox.
hook Install pre-commit hook.
pre-commit <hook> Run pre-commit hooks on all files.
pre-commit-update Update all pre-commit hooks to latest versions.
lint Run pre-commit hooks on all files.
mypy Run mypy on all files.

Use quotes (" ") if command contains flags (-h / --help)
Expand Down Expand Up @@ -60,11 +58,8 @@ tox:
hook:
@poetry run pre-commit install

pre-commit:
@poetry run pre-commit run --all-files $(call args, "")

pre-commit-update:
@poetry run pre-commit autoupdate
lint:
@poetry run pre-commit run --all-files

mypy:
@poetry run mypy django_signal_webhooks/
11 changes: 4 additions & 7 deletions manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,14 @@
import sys


def main():
def main() -> None:
"""Run administrative tasks."""
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tests.django.settings")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tests.project.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
msg = "Couldn't import Django. Are you sure it's installed and available on your PYTHONPATH environment variable? Did you forget to activate a virtual environment?"
raise ImportError(msg) from exc
execute_from_command_line(sys.argv)


Expand Down
858 changes: 430 additions & 428 deletions poetry.lock

Large diffs are not rendered by default.

101 changes: 75 additions & 26 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ classifiers = [
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Framework :: Django :: 3.2",
"Framework :: Django :: 4.0",
"Framework :: Django :: 4.1",
Expand Down Expand Up @@ -56,49 +57,96 @@ django-settings-holder = ">=0.1.0"
djangorestframework = { version = ">=3.13.0", optional = true}

[tool.poetry.group.test.dependencies]
pytest = "7.4.0"
coverage = "7.2.7"
pytest = "7.4.3"
coverage = "7.3.2"
pytest-django = "4.5.2"
pytest-freezegun = "0.4.2"
pre-commit = "3.3.3"
tox = "4.6.4"
pre-commit = "3.5.0"
tox = "4.11.3"
tox-gh-actions = "3.1.3"

[tool.poetry.group.docs.dependencies]
mkdocs = "1.4.3"
pymdown-extensions = "10.1"
mkdocs-mermaid2-plugin = "1.0.1"
mkdocs = "1.5.3"
pymdown-extensions = "10.3.1"
mkdocs-mermaid2-plugin = "1.1.1"

[tool.poetry.group.lint.dependencies]
mypy = "1.4.1"
django-stubs = "4.2.3"
djangorestframework-stubs = "3.14.2"
mypy = "1.6.1"
django-stubs = "4.2.6"
djangorestframework-stubs = "3.14.4"

[tool.poetry.extras]
drf = ["djangorestframework"]

[tool.black]
line-length = 120

[tool.ruff]
fix = true
line-length = 120
exclude = [
"tests/*",
]
select = [
"F", # pyflakes
"E", # pycodestyle errors
"I", # isort
"S", # flake8-bandit
"C", # flake8-comprehensions
"B", # flake8-bugbear
"T", # flake8-print
"W", # pycodestyle warnings
"A", # flake8-builtins
"ANN", # flake8-annotations
"ARG", # flake8-unused-arguments
"B", # flake8-bugbear
"BLE", # flake8-blind-except
"C90", # mccabe
"C4", # flake8-comprehensions
"COM", # flake8-commas
"D200", # pydocstyle: One-line docstring should fit on one line
"D201", # pydocstyle: No blank lines allowed before function docstring (found {num_lines})
"D202", # pydocstyle: No blank lines allowed after function docstring (found {num_lines})
"D209", # pydocstyle: Multi-line docstring closing quotes should be on a separate line
"D213", # pydocstyle: Multi-line docstring summary should start at the second line
"DTZ", # flake8-datetimez
"E", # pycodestyle errors
"EM", # flake8-errmsg
"F", # pyflakes
"FBT", # flake8-boolean-trap
"I", # isort
"INP", # flake8-no-pep420
"ISC", # flake8-implicit-str-concat
"N", # pep8-naming
"PERF", # perflint
"PGH", # pygrep-hooks
"PIE", # flake8-pie
"PL", # pylint
"PT", # flake8-pytest-style
"PTH", # flake8-use-pathlib
"PYI", # flake8-pyi
"Q", # flake8-quotes
"RET", # flake8-return
"RSE", # flake8-raise
"RUF", # ruff-specific rules
"S", # flake8-bandit
"SIM", # flake8-simplify
"T20", # flake8-print
"TCH", # flake8-type-checking
"TRY", # tryceratops
"UP", # pyupgrade
"W", # pycodestyle warnings
]
ignore = [
"S101", # assert is OK
"S105", # no hardcoded passwords
"S101", # assert is OK
"S105", # no hardcoded passwords
"S311", # random-module is OK.
"ARG001", # Anused function argument
"ANN101", # Missing type annotation for `self` in method
"ANN102", # Missing type annotation for `cls` in classmethod
"ANN401", # Any is allowed
"RUF012", # No ClassVar required
#
# Conflicting with ruff-format
#
"COM812", # Trailing comma missing
"COM819", # Trailing comma prohibited
"E501", # Line too long
"ISC001", # Implicitly concatenated string literals on one line
"Q000", # Single quotes found but double quotes preferred
"Q001", # Single quote multiline found but double quotes preferred
"Q002", # Single quote docstring found but double quotes preferred
"Q003", # Change outer quotes to avoid escaping inner quotes
"W191", # Indentation contains tabs
]

[tool.ruff.per-file-ignores]
Expand All @@ -115,7 +163,7 @@ known-third-party = [
]

[tool.mypy]
python_version = "3.11"
python_version = "3.12"
warn_return_any = "True"
warn_unused_configs = "True"
plugins = [
Expand Down Expand Up @@ -146,12 +194,12 @@ markers = [
]

[tool.django-stubs]
django_settings_module = "tests.django.settings"
django_settings_module = "tests.project.settings"

[tool.tox]
legacy_tox_ini = """
[tox]
envlist = py{38, 39, 310, 311}-django{32, 40, 41, 42}
envlist = py{38, 39, 310, 311, 312}-django{32, 40, 41, 42}
isolated_build = true
[gh-actions]
Expand All @@ -160,6 +208,7 @@ python =
3.9: py39
3.10: py310
3.11: py311
3.12: py312
[testenv]
allowlist_externals =
Expand Down
25 changes: 14 additions & 11 deletions signal_webhooks/admin.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
from __future__ import annotations

import logging
from typing import TYPE_CHECKING

from django import forms
from django.contrib import admin

from .settings import webhook_settings
from .typing import Optional
from .utils import get_webhookhook_model

if TYPE_CHECKING:
from .typing import Any, Optional

__all__ = [
"WebhookModelForm",
"WebhookAdmin",
Expand All @@ -27,7 +32,7 @@ class Meta:
"auth_token": forms.Textarea,
}

def __init__(self, *args, **kwargs):
def __init__(self, *args: Any, **kwargs: Any) -> None:
if webhook_settings.HIDE_TOKEN:
instance: Optional[WebhookModel] = kwargs.get("instance")
self._auth_token: Optional[str] = None
Expand All @@ -37,15 +42,13 @@ def __init__(self, *args, **kwargs):

super().__init__(*args, **kwargs)

if webhook_settings.HIDE_TOKEN:
if self._auth_token is not None:
masked_auth_token = self._auth_token.replace(self._auth_token[:-5], "********", 1)
self.fields["auth_token"].help_text += f" Current token: {masked_auth_token}"
if webhook_settings.HIDE_TOKEN and self._auth_token is not None:
masked_auth_token = self._auth_token.replace(self._auth_token[:-5], "********", 1)
self.fields["auth_token"].help_text += f" Current token: {masked_auth_token}"

def clean(self):
if webhook_settings.HIDE_TOKEN:
if self.cleaned_data["auth_token"] == "" and self._auth_token is not None:
self.cleaned_data["auth_token"] = self._auth_token
def clean(self) -> dict[str, Any] | None:
if webhook_settings.HIDE_TOKEN and self.cleaned_data["auth_token"] == "" and self._auth_token is not None:
self.cleaned_data["auth_token"] = self._auth_token
return super().clean()


Expand Down Expand Up @@ -77,6 +80,6 @@ class WebhookAdmin(admin.ModelAdmin):
"last_failure",
]

def lookup_allowed(self, lookup, value): # pragma: no cover
def lookup_allowed(self, lookup: str, value: str) -> bool: # pragma: no cover
# Don't allow lookups involving auth tokens
return not lookup.startswith("auth_token") and super().lookup_allowed(lookup, value)
3 changes: 2 additions & 1 deletion signal_webhooks/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class Meta:

def validate(self, attrs: Dict[str, Any]) -> Dict[str, Any]:
if get_webhookhook_model().objects.filter(ref=attrs["ref"], endpoint=attrs["endpoint"]).exists():
raise ValidationError("Webhook for this model to this endpoint already exists.")
msg = "Webhook for this model to this endpoint already exists."
raise ValidationError(msg)

return attrs
2 changes: 1 addition & 1 deletion signal_webhooks/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
]


class WebhookCancelled(Exception):
class WebhookCancelled(Exception): # noqa: N818
"""Webhook was cancelled before it was sent."""
16 changes: 11 additions & 5 deletions signal_webhooks/fields.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from __future__ import annotations

import logging
from base64 import b64decode, b64encode
from os import urandom
from typing import TYPE_CHECKING

from cryptography.exceptions import InvalidTag
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
Expand All @@ -9,6 +12,9 @@

from .utils import decode_cipher_key

if TYPE_CHECKING:
from .typing import Any

__all__ = [
"TokenField",
]
Expand All @@ -20,7 +26,7 @@
class TokenField(models.CharField):
"""Encrypt token with a cipher before saving it."""

def from_db_value(self, value: str, *args, **kwargs) -> str:
def from_db_value(self, value: str, *args: Any, **kwargs: Any) -> str: # noqa: ARG002
if not value:
return value

Expand All @@ -34,11 +40,12 @@ def from_db_value(self, value: str, *args, **kwargs) -> str:
try:
decrypted_token = cipher.decrypt(nonce, data, None)
except InvalidTag as error:
raise ValidationError("Wrong cipher key.") from error
msg = "Wrong cipher key."
raise ValidationError(msg) from error

return decrypted_token.decode()

def get_prep_value(self, value: str, *args, **kwargs) -> str:
def get_prep_value(self, value: str, *args: Any, **kwargs: Any) -> str: # noqa: ARG002
if not value:
return value

Expand All @@ -47,5 +54,4 @@ def get_prep_value(self, value: str, *args, **kwargs) -> str:
nonce = urandom(12)
cipher = AESGCM(key)
encrypted_token = cipher.encrypt(nonce, value.encode(encoding="utf-8"), None)
encoded_token = b64encode(nonce + encrypted_token).decode()
return encoded_token
return b64encode(nonce + encrypted_token).decode()
Loading

0 comments on commit f9b57a0

Please sign in to comment.