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 1/5] 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


From 5c18e15cb522ecc0fc76a5679430b84e1bcc9ebf Mon Sep 17 00:00:00 2001
From: Dominik George <dominik.george@teckids.org>
Date: Sun, 5 Jun 2022 16:56:57 +0200
Subject: [PATCH 2/5] Implement icon_choices

---
 dj_iconify/util.py | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/dj_iconify/util.py b/dj_iconify/util.py
index 2c83e62..042415a 100644
--- a/dj_iconify/util.py
+++ b/dj_iconify/util.py
@@ -1,7 +1,8 @@
 """Utility code used by other parts of django-iconify."""
+import os
 import re
 
-from .conf import COLLECTIONS_ALLOWED, COLLECTIONS_DISALLOWED
+from .conf import COLLECTIONS_ALLOWED, COLLECTIONS_DISALLOWED, JSON_ROOT
 
 
 def split_css_unit(string: str):
@@ -33,3 +34,15 @@ def collection_allowed(collection: str) -> bool:
         return False
 
     return True
+
+
+def icon_choices(collection: str) -> list[tuple[str, str]]:
+    """Get Django model/form choices for icons in one collection."""
+
+    from .types import IconifyJSON
+
+    # Load icon set through Iconify types
+    collection_file = os.path.join(JSON_ROOT, "json", f"{collection}.json")
+    icon_set = IconifyJSON.from_file(collection_file)
+
+    return [(name, name) for name in icon_set.icons.keys()]
-- 
GitLab


From e89ca7f0118be8adf81df7b96ce1ebee720d93df Mon Sep 17 00:00:00 2001
From: Julian Leucker <leuckerj@gmail.com>
Date: Wed, 22 Jun 2022 18:06:37 +0200
Subject: [PATCH 3/5] Fix if statement inside collection_allowed

---
 dj_iconify/util.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dj_iconify/util.py b/dj_iconify/util.py
index 042415a..29d0ff1 100644
--- a/dj_iconify/util.py
+++ b/dj_iconify/util.py
@@ -30,7 +30,7 @@ def collection_allowed(collection: str) -> bool:
     if collection in COLLECTIONS_DISALLOWED:
         return False
 
-    if COLLECTIONS_ALLOWED and collection not in COLLECTIONS_DISALLOWED:
+    if COLLECTIONS_ALLOWED and collection not in COLLECTIONS_ALLOWED:
         return False
 
     return True
-- 
GitLab


From 0f0f74c23d03435ba13bae95a3b0a56ff6c70dfe Mon Sep 17 00:00:00 2001
From: Julian Leucker <leuckerj@gmail.com>
Date: Wed, 22 Jun 2022 18:06:59 +0200
Subject: [PATCH 4/5] Sort icon choices alphabetically

---
 dj_iconify/util.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dj_iconify/util.py b/dj_iconify/util.py
index 29d0ff1..10dcb43 100644
--- a/dj_iconify/util.py
+++ b/dj_iconify/util.py
@@ -45,4 +45,4 @@ def icon_choices(collection: str) -> list[tuple[str, str]]:
     collection_file = os.path.join(JSON_ROOT, "json", f"{collection}.json")
     icon_set = IconifyJSON.from_file(collection_file)
 
-    return [(name, name) for name in icon_set.icons.keys()]
+    return [(name, name) for name in sorted(icon_set.icons.keys())]
-- 
GitLab


From cfbb361885c5bb6978205049ed6249fb06125855 Mon Sep 17 00:00:00 2001
From: Dominik George <dominik.george@teckids.org>
Date: Wed, 22 Jun 2022 18:28:21 +0200
Subject: [PATCH 5/5] Raise KeyError if choices for a disallowed collection are
 requested

---
 dj_iconify/util.py | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/dj_iconify/util.py b/dj_iconify/util.py
index 10dcb43..50e0859 100644
--- a/dj_iconify/util.py
+++ b/dj_iconify/util.py
@@ -41,6 +41,9 @@ def icon_choices(collection: str) -> list[tuple[str, str]]:
 
     from .types import IconifyJSON
 
+    if not collection_allowed(collection):
+        raise KeyError("The collection %s is disallowed." % collection)
+
     # Load icon set through Iconify types
     collection_file = os.path.join(JSON_ROOT, "json", f"{collection}.json")
     icon_set = IconifyJSON.from_file(collection_file)
-- 
GitLab