From 6a9c5f0eb2df94a1b73bb3d73bf1e35a2803f310 Mon Sep 17 00:00:00 2001
From: Konrad Mohrfeldt <konrad.mohrfeldt@farbdev.org>
Date: Wed, 31 Jul 2024 13:44:51 +0200
Subject: [PATCH] feat: encode ProgramEntry.id as UUID

API consumers must not be tempted to parse ids, so we encode them as
UUIDs to prevent that.
---
 program/serializers.py |  2 +-
 program/services.py    | 10 +++++++++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/program/serializers.py b/program/serializers.py
index bbae2a63..cf89e77e 100644
--- a/program/serializers.py
+++ b/program/serializers.py
@@ -1243,7 +1243,7 @@ class RadioSettingsSerializer(serializers.ModelSerializer):
 
 
 class BasicProgramEntrySerializer(serializers.Serializer):
-    id = serializers.CharField()
+    id = serializers.UUIDField()
     start = serializers.DateTimeField()
     end = serializers.DateTimeField()
     timeslot_id = serializers.IntegerField(allow_null=True, source="timeslot.id")
diff --git a/program/services.py b/program/services.py
index 77e57bb3..df7565b5 100644
--- a/program/services.py
+++ b/program/services.py
@@ -18,6 +18,8 @@
 #
 
 import copy
+import hashlib
+import uuid
 from collections.abc import Iterator
 from datetime import datetime, time, timedelta
 
@@ -711,6 +713,12 @@ def get_fallback_show(raise_exceptions: bool = False):
     return fallback_show
 
 
+def uuid_from_string(data: str):
+    hash = hashlib.md5()
+    hash.update(data.encode())
+    return uuid.UUID(hex=hash.hexdigest(), version=4)
+
+
 def generate_program_entries(
     queryset: QuerySet[TimeSlot],
     *,
@@ -726,7 +734,7 @@ def generate_program_entries(
     def create_entry(
         starts_at: datetime, ends_at: datetime, show: Show, timeslot: TimeSlot | None = None
     ):
-        entry_id = f"{starts_at.isoformat()}...{ends_at.isoformat()}"
+        entry_id = uuid_from_string(f"{starts_at.isoformat()}...{ends_at.isoformat()}")
         if cut_at_range_boundaries:
             starts_at = max(starts_at, start)
             ends_at = min(ends_at, end)
-- 
GitLab