From 0c3042570c3a502c5c01ac5f6e4e319e15736a23 Mon Sep 17 00:00:00 2001 From: Tuomas Suutari Date: Fri, 9 Feb 2018 11:33:43 +0200 Subject: [PATCH] Reconfigure API authentication classes Configure the ApiKeyAuthentication via DEFAULT_AUTHENTICATION_CLASSES setting and only set permission classes per API views. This allows having SessionAuthentication and BasicAuthentication in the development environment (in DEBUG mode), which helps the development. --- parkings/api/enforcement/operator.py | 4 +--- parkings/api/enforcement/valid_parking.py | 4 +--- parkings/api/operator/parking.py | 4 +--- parkings/api/public/parking_area.py | 3 ++- parkings/api/public/parking_area_statistics.py | 3 ++- parkings/api/public/urls.py | 14 ++++++++++++-- parkkihubi/settings.py | 14 +++++++++++++- 7 files changed, 32 insertions(+), 14 deletions(-) diff --git a/parkings/api/enforcement/operator.py b/parkings/api/enforcement/operator.py index b495e37c..f83c36f1 100644 --- a/parkings/api/enforcement/operator.py +++ b/parkings/api/enforcement/operator.py @@ -1,6 +1,5 @@ from rest_framework import permissions, serializers, viewsets -from ...authentication import ApiKeyAuthentication from ...models import Operator @@ -16,7 +15,6 @@ class Meta: class OperatorViewSet(viewsets.ReadOnlyModelViewSet): + permission_classes = [permissions.IsAdminUser] queryset = Operator.objects.order_by('name') serializer_class = OperatorSerializer - authentication_classes = [ApiKeyAuthentication] - permission_classes = [permissions.IsAdminUser] diff --git a/parkings/api/enforcement/valid_parking.py b/parkings/api/enforcement/valid_parking.py index b2179360..1042bf6e 100644 --- a/parkings/api/enforcement/valid_parking.py +++ b/parkings/api/enforcement/valid_parking.py @@ -6,7 +6,6 @@ from django.utils.translation import gettext_lazy as _ from rest_framework import permissions, serializers, viewsets -from ...authentication import ApiKeyAuthentication from ...models import Parking @@ -90,8 +89,7 @@ def get_time_old_parkings_visible(default=datetime.timedelta(minutes=15)): class ValidParkingViewSet(viewsets.ReadOnlyModelViewSet): + permission_classes = [permissions.IsAdminUser] queryset = Parking.objects.order_by('-time_end') serializer_class = ValidParkingSerializer filter_class = ValidParkingFilter - authentication_classes = [ApiKeyAuthentication] - permission_classes = [permissions.IsAdminUser] diff --git a/parkings/api/operator/parking.py b/parkings/api/operator/parking.py index 6d32c705..4ddae566 100644 --- a/parkings/api/operator/parking.py +++ b/parkings/api/operator/parking.py @@ -4,7 +4,6 @@ from django.utils.translation import ugettext_lazy as _ from rest_framework import mixins, permissions, serializers, viewsets -from parkings.authentication import ApiKeyAuthentication from parkings.models import Operator, Parking from ..common import ParkingException @@ -87,10 +86,9 @@ def has_object_permission(self, request, view, obj): class OperatorAPIParkingViewSet(mixins.CreateModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, viewsets.GenericViewSet): + permission_classes = [OperatorAPIParkingPermission] queryset = Parking.objects.order_by('time_start') serializer_class = OperatorAPIParkingSerializer - authentication_classes = (ApiKeyAuthentication,) - permission_classes = (OperatorAPIParkingPermission,) def perform_create(self, serializer): serializer.save(operator=self.request.user.operator) diff --git a/parkings/api/public/parking_area.py b/parkings/api/public/parking_area.py index fe9c5a8f..6ca43eab 100644 --- a/parkings/api/public/parking_area.py +++ b/parkings/api/public/parking_area.py @@ -1,4 +1,4 @@ -from rest_framework import viewsets +from rest_framework import permissions, viewsets from rest_framework_gis.pagination import GeoJsonPagination from rest_framework_gis.serializers import ( GeoFeatureModelSerializer, GeometrySerializerMethodField) @@ -24,6 +24,7 @@ class Meta: class PublicAPIParkingAreaViewSet(viewsets.ReadOnlyModelViewSet): + permission_classes = [permissions.AllowAny] queryset = ParkingArea.objects.order_by('origin_id') serializer_class = ParkingAreaSerializer pagination_class = GeoJsonPagination diff --git a/parkings/api/public/parking_area_statistics.py b/parkings/api/public/parking_area_statistics.py index 889ed34f..9a6a9d36 100644 --- a/parkings/api/public/parking_area_statistics.py +++ b/parkings/api/public/parking_area_statistics.py @@ -1,6 +1,6 @@ from django.db.models import Case, Count, Q, When from django.utils import timezone -from rest_framework import serializers, viewsets +from rest_framework import permissions, serializers, viewsets from parkings.models import ParkingArea from parkings.pagination import PublicAPIPagination @@ -33,6 +33,7 @@ class Meta: class PublicAPIParkingAreaStatisticsViewSet(viewsets.ReadOnlyModelViewSet): + permission_classes = [permissions.AllowAny] queryset = ParkingArea.objects.all() serializer_class = ParkingAreaStatisticsSerializer pagination_class = PublicAPIPagination diff --git a/parkings/api/public/urls.py b/parkings/api/public/urls.py index 2f5c8eb5..00e8ff9d 100644 --- a/parkings/api/public/urls.py +++ b/parkings/api/public/urls.py @@ -1,10 +1,20 @@ from django.conf.urls import include, url -from rest_framework.routers import DefaultRouter +from rest_framework import permissions +from rest_framework.routers import APIRootView, DefaultRouter from .parking_area import PublicAPIParkingAreaViewSet from .parking_area_statistics import PublicAPIParkingAreaStatisticsViewSet -router = DefaultRouter() + +class PublicApiRootView(APIRootView): + permission_classes = [permissions.AllowAny] + + +class Router(DefaultRouter): + APIRootView = PublicApiRootView + + +router = Router() router.register(r'parking_area', PublicAPIParkingAreaViewSet, base_name='parkingarea') router.register(r'parking_area_statistics', PublicAPIParkingAreaStatisticsViewSet, base_name='parkingareastatistics') diff --git a/parkkihubi/settings.py b/parkkihubi/settings.py index 49327707..3dddd2fe 100644 --- a/parkkihubi/settings.py +++ b/parkkihubi/settings.py @@ -18,6 +18,7 @@ # Django core settings # ######################## DEBUG = env.bool('DEBUG', default=False) +TIER = env.str('TIER', default='dev') SECRET_KEY = env.str('SECRET_KEY', default=('' if not DEBUG else 'xxx')) ALLOWED_HOSTS = ['*'] @@ -80,7 +81,7 @@ 'parkings', ] -if DEBUG: +if DEBUG and TIER == 'dev': # shell_plus and other goodies INSTALLED_APPS.append("django_extensions") @@ -157,6 +158,17 @@ # Django REST Framework # ######################### REST_FRAMEWORK = { + 'DEFAULT_PERMISSION_CLASSES': [ + # Make nothing accessible to non-admins by default. Viewsets + # should specify permission_classes to override permissions. + 'rest_framework.permissions.IsAdminUser', + ], + 'DEFAULT_AUTHENTICATION_CLASSES': [ + 'parkings.authentication.ApiKeyAuthentication', + ] + ([ # Following two are only for DEBUG mode in dev environment: + 'rest_framework.authentication.SessionAuthentication', + 'rest_framework.authentication.BasicAuthentication', + ] if (DEBUG and TIER == 'dev') else []), 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.NamespaceVersioning', 'ALLOWED_VERSIONS': ('v1',), 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),