Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/api/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@

ROOT_URLCONF = "api.urls"

WSGI_APPLICATION = "desecapi.wsgi.application"
WSGI_APPLICATION = "api.wsgi.application"


DATABASES = {
Expand Down
4 changes: 2 additions & 2 deletions api/desecapi/serializers/records.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ def to_internal_value(self, data):
raise serializers.ValidationError(
{
api_settings.NON_FIELD_ERRORS_KEY: [
f"RRset with conflicting type present: {types_by_position}."
f"RRset with conflicting type present at same subname: {types_by_position}."
" (No other RRsets are allowed alongside CNAME.)"
]
}
Expand Down Expand Up @@ -412,7 +412,7 @@ def get_validators(self):
"type",
"CNAME",
),
message="RRset with conflicting type present: database ({types})."
message="RRset with conflicting type present at same subname: database ({types})."
" (No other RRsets are allowed alongside CNAME.)",
),
]
Expand Down
10 changes: 10 additions & 0 deletions api/desecapi/tests/test_dyndns12update.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,16 @@ def test_ddclient_dyndns2_v4_invalid(self):
self.assertStatus(response, status.HTTP_400_BAD_REQUEST)
self.assertIn("malformed", str(response.data))

def test_ddclient_dyndns2_v4_weird(self):
# These should not throw errors
url = self.reverse("v1:dyndns12update")
for query_string in [
"/https:/update.dedyn.io/example.dedyn.io",
"/&myipv4=%3Cpreserve%3E&myipv6=2a00::/64&:8:a:5:8b61",
]:
response = self.client.get(f"{url}?{query_string}")
self.assertStatus(response, status.HTTP_200_OK)

def test_ddclient_dyndns2_v4_valid_priority(self):
params = {
"domain_name": self.my_domain.name,
Expand Down
4 changes: 2 additions & 2 deletions api/desecapi/tests/test_rrsets_bulk.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,12 @@ def test_bulk_patch_cname_exclusivity(self):
[
{
"non_field_errors": [
"RRset with conflicting type present: 1 (CNAME). (No other RRsets are allowed alongside CNAME.)"
"RRset with conflicting type present at same subname: 1 (CNAME). (No other RRsets are allowed alongside CNAME.)"
]
},
{
"non_field_errors": [
"RRset with conflicting type present: 0 (A), database (A, TXT). (No other RRsets are allowed alongside CNAME.)"
"RRset with conflicting type present at same subname: 0 (A), database (A, TXT). (No other RRsets are allowed alongside CNAME.)"
]
},
],
Expand Down
17 changes: 13 additions & 4 deletions api/desecapi/views/domains.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from django.conf import settings
from django.core.cache import cache
from django.db.models import Subquery
from rest_framework import mixins, viewsets
from rest_framework import mixins, status, viewsets
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated, SAFE_METHODS
from rest_framework.response import Response
Expand Down Expand Up @@ -143,8 +143,17 @@ class SerialListView(APIView):

def get(self, request, *args, **kwargs):
key = "desecapi.views.serials"
serials = cache.get(key)
if serials is None:
# Determine if the last update is older than 60s and nobody is working on it
# If so, start working on it; other workers will keep using the old list
our_update = cache.add(f"{key}.sentinel", True, timeout=60)
if our_update:
serials = get_serials()
cache.get_or_set(key, serials, timeout=60)
cache.set(key, serials, timeout=300) # long expiration, overwritten 1/min
else:
serials = cache.get(key)
if serials is None:
return Response(
data={"detail": "Serial cache not ready"},
status=status.HTTP_409_CONFLICT,
)
return Response(serials)
5 changes: 4 additions & 1 deletion api/desecapi/views/dyndns.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,10 @@ def extra_qname_params(self) -> dict[str, dict[str, str]]:
param_prefix, param_suffix = param.split(":", 1)
except ValueError:
continue
type_ = param_prefix_types[param_prefix]
try:
type_ = param_prefix_types[param_prefix]
except KeyError:
continue

for qname in self._sanitize_qnames(param_suffix):
qnames[qname][type_] = value
Expand Down
8 changes: 4 additions & 4 deletions api/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
captcha~=0.7.1
celery~=5.6.2
coverage~=7.13.4
coverage~=7.14.0
cryptography~=46.0.5
Django~=5.2.7
django-cors-headers~=4.9.0
djangorestframework~=3.16.1
django-celery-email~=3.0.0
django-netfields~=1.3.2
django-netfields~=1.4.1
django-pgtrigger~=4.17.0
django-prometheus~=2.4.1
dnspython~=2.8.0
pyotp~=2.9.0
psycopg[binary]~=3.3.2
psycopg[binary]~=3.3.4
psl-dns~=1.1.1
pylibmc~=1.6.3
pyyaml~=6.0.3
requests~=2.32.5
responses~=0.25.8
responses~=0.26.0
uwsgi~=2.0.31
Loading