diff --git a/netbox/extras/api/views.py b/netbox/extras/api/views.py index 3439f6f3f..0a5303741 100644 --- a/netbox/extras/api/views.py +++ b/netbox/extras/api/views.py @@ -20,7 +20,7 @@ from netbox.api.metadata import ContentTypeMetadata from netbox.api.renderers import TextRenderer from netbox.api.viewsets import NetBoxModelViewSet from utilities.exceptions import RQWorkerNotRunningException -from utilities.utils import copy_safe_request +from utilities.request import copy_safe_request from . import serializers from .mixins import ConfigTemplateRenderMixin diff --git a/netbox/extras/management/commands/runscript.py b/netbox/extras/management/commands/runscript.py index 2098b7a82..160e8813f 100644 --- a/netbox/extras/management/commands/runscript.py +++ b/netbox/extras/management/commands/runscript.py @@ -14,7 +14,7 @@ from extras.context_managers import event_tracking from extras.scripts import get_module_and_script from extras.signals import clear_events from utilities.exceptions import AbortTransaction -from utilities.utils import NetBoxFakeRequest +from utilities.request import NetBoxFakeRequest class Command(BaseCommand): diff --git a/netbox/extras/views.py b/netbox/extras/views.py index b17e3fcf7..553efb2c5 100644 --- a/netbox/extras/views.py +++ b/netbox/extras/views.py @@ -20,9 +20,10 @@ from netbox.views import generic from netbox.views.generic.mixins import TableMixin from utilities.forms import ConfirmationForm, get_field_value from utilities.paginator import EnhancedPaginator, get_paginate_count +from utilities.request import copy_safe_request from utilities.rqworker import get_workers_for_queue from utilities.templatetags.builtins.filters import render_markdown -from utilities.utils import copy_safe_request, count_related, normalize_querydict, shallow_compare_dict +from utilities.utils import count_related, normalize_querydict, shallow_compare_dict from utilities.views import ContentTypePermissionRequiredMixin, get_viewname, register_model_view from . import filtersets, forms, tables from .models import * diff --git a/netbox/utilities/request.py b/netbox/utilities/request.py index 3ae01f326..5571b326d 100644 --- a/netbox/utilities/request.py +++ b/netbox/utilities/request.py @@ -2,11 +2,54 @@ from django.utils.translation import gettext_lazy as _ from netaddr import AddrFormatError, IPAddress from urllib.parse import urlparse +from .constants import HTTP_REQUEST_META_SAFE_COPY + __all__ = ( + 'NetBoxFakeRequest', + 'copy_safe_request', 'get_client_ip', ) +# +# Fake request object +# + +class NetBoxFakeRequest: + """ + A fake request object which is explicitly defined at the module level so it is able to be pickled. It simply + takes what is passed to it as kwargs on init and sets them as instance variables. + """ + def __init__(self, _dict): + self.__dict__ = _dict + + +# +# Utility functions +# + +def copy_safe_request(request): + """ + Copy selected attributes from a request object into a new fake request object. This is needed in places where + thread safe pickling of the useful request data is needed. + """ + meta = { + k: request.META[k] + for k in HTTP_REQUEST_META_SAFE_COPY + if k in request.META and isinstance(request.META[k], str) + } + return NetBoxFakeRequest({ + 'META': meta, + 'COOKIES': request.COOKIES, + 'POST': request.POST, + 'GET': request.GET, + 'FILES': request.FILES, + 'user': request.user, + 'path': request.path, + 'id': getattr(request, 'id', None), # UUID assigned by middleware + }) + + def get_client_ip(request, additional_headers=()): """ Return the client (source) IP address of the given request. diff --git a/netbox/utilities/utils.py b/netbox/utilities/utils.py index 6efe86119..8f0d357b2 100644 --- a/netbox/utilities/utils.py +++ b/netbox/utilities/utils.py @@ -21,7 +21,6 @@ from mptt.models import MPTTModel from dcim.choices import CableLengthUnitChoices, WeightUnitChoices from extras.utils import is_taggable from netbox.config import get_config -from utilities.constants import HTTP_REQUEST_META_SAFE_COPY from .constants import HTML_ALLOWED_ATTRIBUTES, HTML_ALLOWED_TAGS from .string import title @@ -435,41 +434,6 @@ def content_type_identifier(ct): return f'{ct.app_label}.{ct.model}' -# -# Fake request object -# - -class NetBoxFakeRequest: - """ - A fake request object which is explicitly defined at the module level so it is able to be pickled. It simply - takes what is passed to it as kwargs on init and sets them as instance variables. - """ - def __init__(self, _dict): - self.__dict__ = _dict - - -def copy_safe_request(request): - """ - Copy selected attributes from a request object into a new fake request object. This is needed in places where - thread safe pickling of the useful request data is needed. - """ - meta = { - k: request.META[k] - for k in HTTP_REQUEST_META_SAFE_COPY - if k in request.META and isinstance(request.META[k], str) - } - return NetBoxFakeRequest({ - 'META': meta, - 'COOKIES': request.COOKIES, - 'POST': request.POST, - 'GET': request.GET, - 'FILES': request.FILES, - 'user': request.user, - 'path': request.path, - 'id': getattr(request, 'id', None), # UUID assigned by middleware - }) - - def clean_html(html, schemes): """ Sanitizes HTML based on a whitelist of allowed tags and attributes.