mirror of
				https://github.com/netbox-community/netbox.git
				synced 2024-05-10 07:54:54 +00:00 
			
		
		
		
	Fixes #1385: Connected device API endpoint no longer requires authentication if LOGIN_REQUIRED=False
This commit is contained in:
		@@ -3,7 +3,6 @@ from collections import OrderedDict
 | 
			
		||||
 | 
			
		||||
from rest_framework.decorators import detail_route
 | 
			
		||||
from rest_framework.mixins import ListModelMixin
 | 
			
		||||
from rest_framework.permissions import IsAuthenticated
 | 
			
		||||
from rest_framework.response import Response
 | 
			
		||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ViewSet
 | 
			
		||||
 | 
			
		||||
@@ -21,7 +20,7 @@ from dcim import filters
 | 
			
		||||
from extras.api.serializers import RenderedGraphSerializer
 | 
			
		||||
from extras.api.views import CustomFieldModelViewSet
 | 
			
		||||
from extras.models import Graph, GRAPH_TYPE_INTERFACE, GRAPH_TYPE_SITE
 | 
			
		||||
from utilities.api import ServiceUnavailable, WritableSerializerMixin
 | 
			
		||||
from utilities.api import IsAuthenticatedOrLoginNotRequired, ServiceUnavailable, WritableSerializerMixin
 | 
			
		||||
from .exceptions import MissingFilterException
 | 
			
		||||
from . import serializers
 | 
			
		||||
 | 
			
		||||
@@ -387,7 +386,7 @@ class ConnectedDeviceViewSet(ViewSet):
 | 
			
		||||
    * `peer-device`: The name of the peer device
 | 
			
		||||
    * `peer-interface`: The name of the peer interface
 | 
			
		||||
    """
 | 
			
		||||
    permission_classes = [IsAuthenticated]
 | 
			
		||||
    permission_classes = [IsAuthenticatedOrLoginNotRequired]
 | 
			
		||||
 | 
			
		||||
    def get_view_name(self):
 | 
			
		||||
        return "Connected Device Locator"
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,10 @@ from django.conf import settings
 | 
			
		||||
from django.contrib.contenttypes.models import ContentType
 | 
			
		||||
 | 
			
		||||
from rest_framework import authentication, exceptions
 | 
			
		||||
from rest_framework.compat import is_authenticated
 | 
			
		||||
from rest_framework.exceptions import APIException
 | 
			
		||||
from rest_framework.pagination import LimitOffsetPagination
 | 
			
		||||
from rest_framework.permissions import DjangoModelPermissions, SAFE_METHODS
 | 
			
		||||
from rest_framework.permissions import BasePermission, DjangoModelPermissions, SAFE_METHODS
 | 
			
		||||
from rest_framework.serializers import Field, ValidationError
 | 
			
		||||
 | 
			
		||||
from users.models import Token
 | 
			
		||||
@@ -20,6 +21,10 @@ class ServiceUnavailable(APIException):
 | 
			
		||||
    default_detail = "Service temporarily unavailable, please try again later."
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Authentication
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
class TokenAuthentication(authentication.TokenAuthentication):
 | 
			
		||||
    """
 | 
			
		||||
    A custom authentication scheme which enforces Token expiration times.
 | 
			
		||||
@@ -61,6 +66,20 @@ class TokenPermissions(DjangoModelPermissions):
 | 
			
		||||
        return super(TokenPermissions, self).has_permission(request, view)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class IsAuthenticatedOrLoginNotRequired(BasePermission):
 | 
			
		||||
    """
 | 
			
		||||
    Returns True if the user is authenticated or LOGIN_REQUIRED is False.
 | 
			
		||||
    """
 | 
			
		||||
    def has_permission(self, request, view):
 | 
			
		||||
        if not settings.LOGIN_REQUIRED:
 | 
			
		||||
            return True
 | 
			
		||||
        return request.user and is_authenticated(request.user)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Serializers
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
class ChoiceFieldSerializer(Field):
 | 
			
		||||
    """
 | 
			
		||||
    Represent a ChoiceField as {'value': <DB value>, 'label': <string>}.
 | 
			
		||||
@@ -98,6 +117,10 @@ class ContentTypeFieldSerializer(Field):
 | 
			
		||||
            raise ValidationError("Invalid content type")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Mixins
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
class ModelValidationMixin(object):
 | 
			
		||||
    """
 | 
			
		||||
    Enforce a model's validation through clean() when validating serializer data. This is necessary to ensure we're
 | 
			
		||||
@@ -119,6 +142,10 @@ class WritableSerializerMixin(object):
 | 
			
		||||
        return self.serializer_class
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Pagination
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
class OptionalLimitOffsetPagination(LimitOffsetPagination):
 | 
			
		||||
    """
 | 
			
		||||
    Override the stock paginator to allow setting limit=0 to disable pagination for a request. This returns all objects
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user