mirror of
https://github.com/netbox-community/netbox.git
synced 2026-01-25 21:09:59 -06:00
Implements #2006 - run reports and scripts in the background
This commit is contained in:
@@ -42,3 +42,25 @@ ADVISORY_LOCK_KEYS = {
|
||||
'available-prefixes': 100100,
|
||||
'available-ips': 100200,
|
||||
}
|
||||
|
||||
#
|
||||
# HTTP Request META safe copy
|
||||
#
|
||||
|
||||
HTTP_REQUEST_META_SAFE_COPY = [
|
||||
'CONTENT_LENGTH',
|
||||
'CONTENT_TYPE',
|
||||
'HTTP_ACCEPT',
|
||||
'HTTP_ACCEPT_ENCODING',
|
||||
'HTTP_ACCEPT_LANGUAGE',
|
||||
'HTTP_HOST',
|
||||
'HTTP_REFERER',
|
||||
'HTTP_USER_AGENT',
|
||||
'QUERY_STRING',
|
||||
'REMOTE_ADDR',
|
||||
'REMOTE_HOST',
|
||||
'REMOTE_USER',
|
||||
'REQUEST_METHOD',
|
||||
'SERVER_NAME',
|
||||
'SERVER_PORT',
|
||||
]
|
||||
|
||||
@@ -5,11 +5,12 @@ from collections import OrderedDict
|
||||
from django.core.serializers import serialize
|
||||
from django.db.models import Count, OuterRef, Subquery
|
||||
from django.http import QueryDict
|
||||
from django.http.request import HttpRequest
|
||||
from jinja2 import Environment
|
||||
|
||||
from dcim.choices import CableLengthUnitChoices
|
||||
from extras.utils import is_taggable
|
||||
|
||||
from utilities.constants import HTTP_REQUEST_META_SAFE_COPY
|
||||
|
||||
def csv_format(data):
|
||||
"""
|
||||
@@ -257,3 +258,37 @@ def flatten_dict(d, prefix='', separator='.'):
|
||||
else:
|
||||
ret[key] = v
|
||||
return ret
|
||||
|
||||
|
||||
#
|
||||
# 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, *args, **kwargs):
|
||||
for k, v in kwargs.items():
|
||||
setattr(self, k, v)
|
||||
|
||||
|
||||
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,
|
||||
'POST': request.POST,
|
||||
'GET': request.GET,
|
||||
'FILES': request.FILES,
|
||||
'user': request.user,
|
||||
'path': request.path
|
||||
})
|
||||
|
||||
@@ -39,6 +39,40 @@ from .paginator import EnhancedPaginator, get_paginate_count
|
||||
# Mixins
|
||||
#
|
||||
|
||||
class ContentTypePermissionRequiredMixin(AccessMixin):
|
||||
"""
|
||||
Similar to Django's built-in PermissionRequiredMixin, but extended to check model-level permission assignments.
|
||||
This is related to ObjectPermissionRequiredMixin, except that is does not enforce object-level permissions,
|
||||
and fits within NetBox's custom permission enforcement system.
|
||||
|
||||
additional_permissions: An optional iterable of statically declared permissions to evaluate in addition to those
|
||||
derived from the object type
|
||||
"""
|
||||
additional_permissions = list()
|
||||
|
||||
def get_required_permission(self):
|
||||
"""
|
||||
Return the specific permission necessary to perform the requested action on an object.
|
||||
"""
|
||||
raise NotImplementedError(f"{self.__class__.__name__} must implement get_required_permission()")
|
||||
|
||||
def has_permission(self):
|
||||
user = self.request.user
|
||||
permission_required = self.get_required_permission()
|
||||
|
||||
# Check that the user has been granted the required permission(s).
|
||||
if user.has_perms((permission_required, *self.additional_permissions)):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if not self.has_permission():
|
||||
return self.handle_no_permission()
|
||||
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
|
||||
class ObjectPermissionRequiredMixin(AccessMixin):
|
||||
"""
|
||||
Similar to Django's built-in PermissionRequiredMixin, but extended to check for both model-level and object-level
|
||||
|
||||
Reference in New Issue
Block a user