From dfc3b4e3cef78abe24bebc335896ebdde4e56e46 Mon Sep 17 00:00:00 2001
From: Dominik George <dominik.george@teckids.org>
Date: Sun, 5 Jun 2022 16:45:12 +0200
Subject: [PATCH] Implement allow/disallow list for collection names

Advances #6
---
 dj_iconify/conf.py  |  3 +++
 dj_iconify/util.py  | 14 ++++++++++++++
 dj_iconify/views.py | 13 +++++++++++++
 3 files changed, 30 insertions(+)

diff --git a/dj_iconify/conf.py b/dj_iconify/conf.py
index b8bec8d..f78309b 100644
--- a/dj_iconify/conf.py
+++ b/dj_iconify/conf.py
@@ -4,3 +4,6 @@ from django.conf import settings
 _prefix = "ICONIFY_"
 
 JSON_ROOT = getattr(settings, f"{_prefix}JSON_ROOT")
+
+COLLECTIONS_ALLOWED = getattr(settings, f"{_prefix}COLLECTIONS_ALLOWED", [])
+COLLECTIONS_DISALLOWED = getattr(settings, f"{_prefix}COLLECTIONS_DISALLOWED", [])
diff --git a/dj_iconify/util.py b/dj_iconify/util.py
index 899ee18..2c83e62 100644
--- a/dj_iconify/util.py
+++ b/dj_iconify/util.py
@@ -1,6 +1,8 @@
 """Utility code used by other parts of django-iconify."""
 import re
 
+from .conf import COLLECTIONS_ALLOWED, COLLECTIONS_DISALLOWED
+
 
 def split_css_unit(string: str):
     """Split string into value and unit.
@@ -19,3 +21,15 @@ def split_css_unit(string: str):
     unit = string[len(_value[0]) :]
 
     return value, unit
+
+
+def collection_allowed(collection: str) -> bool:
+    """Determine whether a collection is allowed by settings."""
+
+    if collection in COLLECTIONS_DISALLOWED:
+        return False
+
+    if COLLECTIONS_ALLOWED and collection not in COLLECTIONS_DISALLOWED:
+        return False
+
+    return True
diff --git a/dj_iconify/views.py b/dj_iconify/views.py
index f609de3..c4709ec 100644
--- a/dj_iconify/views.py
+++ b/dj_iconify/views.py
@@ -12,6 +12,7 @@ from django.views.generic import View
 
 from .conf import JSON_ROOT
 from .types import IconifyJSON
+from .util import collection_allowed
 
 
 class BaseJSONView(View):
@@ -89,6 +90,10 @@ class CollectionView(BaseJSONView):
         if collection is None or not re.match(r"[A-Za-z0-9-]+", collection):
             return HttpResponseBadRequest("You must provide a valid prefix name.")
 
+        # Check whether this collection is allowed
+        if not collection_allowed(collection):
+            raise Http404(f"Collection {collection} not allowed")
+
         # Load icon set through Iconify types
         collection_file = os.path.join(JSON_ROOT, "json", f"{collection}.json")
         try:
@@ -123,6 +128,10 @@ class IconifyJSONView(BaseJSONView):
         if icons is not None:
             icons = icons.split(",")
 
+        # Check whether this collection is allowed
+        if not collection_allowed(collection):
+            raise Http404(f"Collection {collection} not allowed")
+
         # Load icon set through Iconify types
         collection_file = os.path.join(JSON_ROOT, "json", f"{collection}.json")
         try:
@@ -151,6 +160,10 @@ class IconifySVGView(View):
         rotate = request.GET.get("rotate", None)
         flip = request.GET.get("flip", None)
 
+        # Check whether this collection is allowed
+        if not collection_allowed(collection):
+            raise Http404(f"Collection {collection} not allowed")
+
         # Load icon set through Iconify types
         collection_file = os.path.join(JSON_ROOT, "json", f"{collection}.json")
         try:
-- 
GitLab