diff --git a/dj_iconify/conf.py b/dj_iconify/conf.py index b8bec8d611659c6e244769875b486c2fb2e8dba4..f78309bbd805a2153ec1f363e9daabff2c2752b7 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 899ee18c00000d99e169b95db00a62d457039c4f..50e0859ad225286a03dc1002e04347dde804fb85 100644 --- a/dj_iconify/util.py +++ b/dj_iconify/util.py @@ -1,6 +1,9 @@ """Utility code used by other parts of django-iconify.""" +import os import re +from .conf import COLLECTIONS_ALLOWED, COLLECTIONS_DISALLOWED, JSON_ROOT + def split_css_unit(string: str): """Split string into value and unit. @@ -19,3 +22,30 @@ 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_ALLOWED: + 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 + + 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) + + return [(name, name) for name in sorted(icon_set.icons.keys())] diff --git a/dj_iconify/views.py b/dj_iconify/views.py index f609de3983f08814adb933a5cb8da25a19bfeef9..c4709ec7e135713a57ac3353caa39e649377137f 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: