Skip to content

Commit

Permalink
[api] Added ScopedThrottling #34
Browse files Browse the repository at this point in the history
closes #34
  • Loading branch information
ManishShah120 committed Jan 6, 2021
1 parent b130a44 commit 4d6e446
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 28 deletions.
42 changes: 15 additions & 27 deletions openwisp_ipam/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@
Subnet = swapper.load_model('openwisp_ipam', 'Subnet')


class ProtectedAPIMixin(object):
authentication_classes = [BearerAuthentication, SessionAuthentication]
permission_classes = [DjangoModelPermissions]
throttle_scope = 'ipam'


class ListViewPagination(pagination.PageNumberPagination):
page_size = 10
page_size_query_param = 'page_size'
Expand Down Expand Up @@ -137,57 +143,45 @@ def index_of(self, address):
return index


class AvailableIpView(RetrieveAPIView):
class AvailableIpView(ProtectedAPIMixin, RetrieveAPIView):
subnet_model = Subnet
queryset = IpAddress.objects.none()
authentication_classes = (BearerAuthentication, SessionAuthentication)
permission_classes = (DjangoModelPermissions,)

def get(self, request, *args, **kwargs):
subnet = get_object_or_404(self.subnet_model, pk=self.kwargs['subnet_id'])
return Response(subnet.get_next_available_ip())


class IpAddressListCreateView(ListCreateAPIView):
class IpAddressListCreateView(ProtectedAPIMixin, ListCreateAPIView):
subnet_model = Subnet
serializer_class = IpAddressSerializer
authentication_classes = (BearerAuthentication, SessionAuthentication)
permission_classes = (DjangoModelPermissions,)
pagination_class = ListViewPagination

def get_queryset(self):
subnet = get_object_or_404(self.subnet_model, pk=self.kwargs['subnet_id'])
return subnet.ipaddress_set.all().order_by('ip_address')


class SubnetListCreateView(ListCreateAPIView):
class SubnetListCreateView(ProtectedAPIMixin, ListCreateAPIView):
serializer_class = SubnetSerializer
authentication_classes = (BearerAuthentication, SessionAuthentication)
permission_classes = (DjangoModelPermissions,)
pagination_class = ListViewPagination
queryset = Subnet.objects.all()


class SubnetView(RetrieveUpdateDestroyAPIView):
class SubnetView(ProtectedAPIMixin, RetrieveUpdateDestroyAPIView):
serializer_class = SubnetSerializer
authentication_classes = (BearerAuthentication, SessionAuthentication)
permission_classes = (DjangoModelPermissions,)
queryset = Subnet.objects.all()


class IpAddressView(RetrieveUpdateDestroyAPIView):
class IpAddressView(ProtectedAPIMixin, RetrieveUpdateDestroyAPIView):
serializer_class = IpAddressSerializer
authentication_classes = (BearerAuthentication, SessionAuthentication)
permission_classes = (DjangoModelPermissions,)
queryset = IpAddress.objects.all()


class RequestIPView(CreateAPIView):
class RequestIPView(ProtectedAPIMixin, CreateAPIView):
subnet_model = Subnet
queryset = IpAddress.objects.none()
serializer_class = IpRequestSerializer
authentication_classes = (BearerAuthentication, SessionAuthentication)
permission_classes = (DjangoModelPermissions,)

def post(self, request, *args, **kwargs):
options = {'description': request.data.get('description')}
Expand All @@ -202,12 +196,10 @@ def post(self, request, *args, **kwargs):
return Response(None)


class ImportSubnetView(CreateAPIView):
class ImportSubnetView(ProtectedAPIMixin, CreateAPIView):
subnet_model = Subnet
queryset = Subnet.objects.none()
serializer_class = ImportSubnetSerializer
authentication_classes = (BearerAuthentication, SessionAuthentication)
permission_classes = (DjangoModelPermissions,)

def post(self, request, *args, **kwargs):
file = request.FILES['csvfile']
Expand All @@ -220,12 +212,10 @@ def post(self, request, *args, **kwargs):
return Response({'detail': _('Data imported successfully.')})


class ExportSubnetView(CreateAPIView):
class ExportSubnetView(ProtectedAPIMixin, CreateAPIView):
subnet_model = Subnet
queryset = Subnet.objects.none()
serializer_class = serializers.Serializer
authentication_classes = (BearerAuthentication, SessionAuthentication)
permission_classes = (DjangoModelPermissions,)

def post(self, request, *args, **kwargs):
response = HttpResponse(content_type='text/csv')
Expand All @@ -235,12 +225,10 @@ def post(self, request, *args, **kwargs):
return response


class SubnetHostsView(ListAPIView):
class SubnetHostsView(ProtectedAPIMixin, ListAPIView):
subnet_model = Subnet
queryset = Subnet.objects.none()
serializer_class = HostsResponseSerializer
authentication_classes = (BearerAuthentication, SessionAuthentication)
permission_classes = (DjangoModelPermissions,)
pagination_class = HostsListPagination

def get_queryset(self):
Expand Down
9 changes: 8 additions & 1 deletion openwisp_ipam/apps.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.conf import settings
from openwisp_utils.api.apps import ApiAppConfig
from openwisp_utils.utils import register_menu_items
from openwisp_utils.utils import default_or_test, register_menu_items
from swapper import get_model_name

from .compat import patch_ipaddress_lib
Expand All @@ -9,7 +10,13 @@ class OpenWispIpamConfig(ApiAppConfig):
name = 'openwisp_ipam'
verbose_name = 'IPAM'

API_ENABLED = getattr(settings, 'OPENWISP_IPAM_API')
REST_FRAMEWORK_SETTINGS = {
'DEFAULT_THROTTLE_RATES': {'ipam': default_or_test('400/hour', None)},
}

def ready(self, *args, **kwargs):
super().ready(*args, **kwargs)
patch_ipaddress_lib()
items = [
{'model': get_model_name('openwisp_ipam', 'Subnet')},
Expand Down
1 change: 1 addition & 0 deletions tests/openwisp2/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
STATIC_URL = '/static/'
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
OPENWISP_USERS_AUTH_API = True
OPENWISP_IPAM_API = True

if TESTING:
OPENWISP_ORGANIZATION_USER_ADMIN = True
Expand Down

0 comments on commit 4d6e446

Please sign in to comment.