From 5f20bf913dd6562f2015405c64174989971c1a05 Mon Sep 17 00:00:00 2001 From: florimondmanca Date: Sun, 5 Dec 2021 18:20:03 +0100 Subject: [PATCH] Explore swappable API key model functionality --- src/rest_framework_api_key/admin.py | 4 +-- src/rest_framework_api_key/models.py | 32 +++++++++++++++++++++-- src/rest_framework_api_key/permissions.py | 4 +-- test_project/project/settings.py | 5 ++++ 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/rest_framework_api_key/admin.py b/src/rest_framework_api_key/admin.py index 759de90..d812123 100644 --- a/src/rest_framework_api_key/admin.py +++ b/src/rest_framework_api_key/admin.py @@ -4,7 +4,7 @@ from django.db import models from django.http.request import HttpRequest -from .models import AbstractAPIKey, APIKey +from .models import AbstractAPIKey class APIKeyModelAdmin(admin.ModelAdmin): @@ -55,6 +55,4 @@ def save_model( obj.save() -admin.site.register(APIKey, APIKeyModelAdmin) - APIKeyAdmin = APIKeyModelAdmin # Compatibility with <1.3 diff --git a/src/rest_framework_api_key/models.py b/src/rest_framework_api_key/models.py index 4317b83..083d5b0 100644 --- a/src/rest_framework_api_key/models.py +++ b/src/rest_framework_api_key/models.py @@ -1,6 +1,8 @@ import typing -from django.core.exceptions import ValidationError +from django.apps import apps as django_apps +from django.conf import settings +from django.core.exceptions import ImproperlyConfigured, ValidationError from django.db import models from django.utils import timezone @@ -142,5 +144,31 @@ def __str__(self) -> str: return str(self.name) +def get_swappable_setting() -> str: + if not hasattr(settings, "API_KEY_MODEL"): + # Ensure a default value is set. + settings.API_KEY_MODEL = "rest_framework_api_key.APIKey" + + return "API_KEY_MODEL" + + class APIKey(AbstractAPIKey): - pass + class Meta(AbstractAPIKey.Meta): + swappable = get_swappable_setting() + + +def get_api_key_model() -> typing.Type[AbstractAPIKey]: + """ + Return the API key model that is active in this project. + """ + try: + return django_apps.get_model(settings.API_KEY_MODEL, require_ready=False) + except ValueError: + raise ImproperlyConfigured( + "API_KEY_MODEL must be of the form 'app_label.model_name'" + ) + except LookupError: + raise ImproperlyConfigured( + "API_KEY_MODEL refers to model '%s' that has not been installed" + % settings.API_KEY_MODEL + ) diff --git a/src/rest_framework_api_key/permissions.py b/src/rest_framework_api_key/permissions.py index 29d6144..cb322da 100644 --- a/src/rest_framework_api_key/permissions.py +++ b/src/rest_framework_api_key/permissions.py @@ -4,7 +4,7 @@ from django.http import HttpRequest from rest_framework import permissions -from .models import AbstractAPIKey, APIKey +from .models import AbstractAPIKey, get_api_key_model class KeyParser: @@ -59,4 +59,4 @@ def has_object_permission( class HasAPIKey(BaseHasAPIKey): - model = APIKey + model = get_api_key_model() diff --git a/test_project/project/settings.py b/test_project/project/settings.py index 6f1c183..e27d8fb 100644 --- a/test_project/project/settings.py +++ b/test_project/project/settings.py @@ -82,3 +82,8 @@ # Static files (CSS, JavaScript, Images) STATIC_URL = "/static/" + + +# API keys + +API_KEY_MODEL = "heroes.HeroAPIKey"