mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
fix
This commit is contained in:
@@ -17,7 +17,7 @@ from modoboa.admin.api.v1 import viewsets as v1_viewsets
|
||||
from modoboa.core import models as core_models
|
||||
from modoboa.lib import renderers as lib_renderers
|
||||
from modoboa.lib import viewsets as lib_viewsets
|
||||
from modoboa.lib.throttle import UserDdosPerView
|
||||
from modoboa.lib.throttle import UserDdosPerView, UserLesserDdosUser
|
||||
|
||||
from ... import lib
|
||||
from ... import models
|
||||
@@ -53,7 +53,14 @@ class DomainViewSet(lib_viewsets.RevisionModelMixin,
|
||||
permission_classes = (
|
||||
permissions.IsAuthenticated, permissions.DjangoModelPermissions,
|
||||
)
|
||||
throttle_classes = [UserDdosPerView, UserRateThrottle]
|
||||
throttle_classes = [UserDdosPerView]
|
||||
|
||||
def get_throttles(self):
|
||||
if self.action in ['administrators']:
|
||||
self.throttle_classes.append(UserLesserDdosUser)
|
||||
else:
|
||||
self.throttle_classes.append(UserDdosPerView)
|
||||
return super().get_throttles()
|
||||
|
||||
def get_queryset(self):
|
||||
"""Filter queryset based on current user."""
|
||||
@@ -163,6 +170,14 @@ class AccountViewSet(v1_viewsets.AccountViewSet):
|
||||
filter_backends = (filters.SearchFilter, dj_filters.DjangoFilterBackend)
|
||||
filterset_class = AccountFilterSet
|
||||
|
||||
def get_throttles(self):
|
||||
if self.action in ['validate']:
|
||||
self.throttle_classes.append(UserLesserDdosUser)
|
||||
else:
|
||||
self.throttle_classes.append(UserDdosPerView)
|
||||
return super().get_throttles()
|
||||
|
||||
|
||||
def get_serializer_class(self):
|
||||
if self.action in ["create", "validate", "update", "partial_update"]:
|
||||
return serializers.WritableAccountSerializer
|
||||
@@ -216,7 +231,15 @@ class IdentityViewSet(viewsets.ViewSet):
|
||||
|
||||
permission_classes = (permissions.IsAuthenticated, )
|
||||
serializer_class = None
|
||||
throttle_classes = [UserDdosPerView, UserRateThrottle]
|
||||
throttle_classes = [UserDdosPerView]
|
||||
|
||||
def get_throttles(self):
|
||||
if self.action in ['list']:
|
||||
self.throttle_classes.append(UserLesserDdosUser)
|
||||
else:
|
||||
self.throttle_classes.append(UserDdosPerView)
|
||||
return super().get_throttles()
|
||||
|
||||
|
||||
def list(self, request, **kwargs):
|
||||
"""Return all identities."""
|
||||
@@ -256,7 +279,7 @@ class AliasViewSet(v1_viewsets.AliasViewSet):
|
||||
"""Viewset for Alias."""
|
||||
|
||||
serializer_class = serializers.AliasSerializer
|
||||
throttle_classes = [UserDdosPerView, UserRateThrottle]
|
||||
throttle_classes = [UserDdosPerView, UserLesserDdosUser]
|
||||
|
||||
@action(methods=["post"], detail=False)
|
||||
def validate(self, request, **kwargs):
|
||||
|
||||
@@ -12,11 +12,12 @@ from drf_spectacular.utils import extend_schema
|
||||
from rest_framework import response, status
|
||||
from rest_framework_simplejwt import views as jwt_views
|
||||
from rest_framework_simplejwt.exceptions import InvalidToken, TokenError
|
||||
from rest_framework.throttling import ScopedRateThrottle, UserRateThrottle
|
||||
from rest_framework.throttling import ScopedRateThrottle
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from modoboa.core.password_hashers import get_password_hasher
|
||||
from modoboa.core.utils import check_for_updates
|
||||
from modoboa.lib.throttle import UserLesserDdosUser
|
||||
from modoboa.parameters import tools as param_tools
|
||||
|
||||
from smtplib import SMTPException
|
||||
@@ -178,7 +179,7 @@ class PasswordResetConfirmView(APIView):
|
||||
class ComponentsInformationAPIView(APIView):
|
||||
"""Retrieve information about installed components."""
|
||||
|
||||
throttle_classes = [UserRateThrottle]
|
||||
throttle_classes = [UserLesserDdosUser]
|
||||
|
||||
@extend_schema(responses=serializers.ModoboaComponentSerializer(many=True))
|
||||
def get(self, request, *args, **kwargs):
|
||||
|
||||
@@ -18,6 +18,7 @@ from modoboa.admin.api.v1 import serializers as admin_v1_serializers
|
||||
from modoboa.core.api.v1 import serializers as core_v1_serializers
|
||||
from modoboa.core.api.v1 import viewsets as core_v1_viewsets
|
||||
from modoboa.lib import pagination
|
||||
from modoboa.lib.throttle import UserLesserDdosUser, UserDdosPerView
|
||||
|
||||
from ... import constants
|
||||
from ... import models
|
||||
@@ -27,6 +28,12 @@ from . import serializers
|
||||
class AccountViewSet(core_v1_viewsets.AccountViewSet):
|
||||
"""Account viewset."""
|
||||
|
||||
def get_throttles(self):
|
||||
if self.action in ['me']:
|
||||
self.throttle_classes.append(UserLesserDdosUser)
|
||||
return super().get_throttles()
|
||||
|
||||
|
||||
@extend_schema(responses=admin_v1_serializers.AccountSerializer)
|
||||
@action(methods=["get"], detail=False)
|
||||
def me(self, request):
|
||||
@@ -172,6 +179,7 @@ class LanguageViewSet(viewsets.ViewSet):
|
||||
permission_classes = (
|
||||
permissions.IsAuthenticated,
|
||||
)
|
||||
throttle_classes = [UserRateThrottle]
|
||||
|
||||
def list(self, request, *args, **kwargs):
|
||||
languages = [
|
||||
|
||||
@@ -194,11 +194,13 @@ MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
|
||||
|
||||
REST_FRAMEWORK = {
|
||||
'DEFAULT_THROTTLE_RATES': {
|
||||
'user': '100/minute',
|
||||
'ddos': '1/second',
|
||||
'user': '300/minute',
|
||||
'ddos': '5/second',
|
||||
'ddos_lesser': '10/second',
|
||||
'login': '5/minute',
|
||||
'password_recovery_request': '6/hour',
|
||||
'password_recovery_totp_check': '20/hour',
|
||||
'password_recovery_apply': '20/hour'
|
||||
'password_recovery_apply': '40/hour'
|
||||
},
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
'modoboa.core.drf_authentication.JWTAuthenticationWith2FA',
|
||||
|
||||
@@ -15,3 +15,19 @@ class UserDdosPerView(SimpleRateThrottle):
|
||||
'scope': hash(f"{view.basename}_{view.name}"),
|
||||
'ident': ident
|
||||
}
|
||||
|
||||
class UserLesserDdosUser(SimpleRateThrottle):
|
||||
"""Custom Throttle class for rest_framework. The throttling is applied on a per view basis for authentificated users."""
|
||||
|
||||
scope = 'ddos_lesser'
|
||||
|
||||
def get_cache_key(self, request, view):
|
||||
if request.user and request.user.is_authenticated:
|
||||
ident = request.user.pk
|
||||
else:
|
||||
ident = self.get_ident(request)
|
||||
|
||||
return self.cache_format % {
|
||||
'scope': self.scope,
|
||||
'ident': ident
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ from rest_framework.permissions import DjangoModelPermissions, IsAuthenticated
|
||||
from rest_framework.throttling import UserRateThrottle
|
||||
|
||||
from modoboa.admin import models as admin_models
|
||||
from modoboa.lib.throttle import UserDdosPerView
|
||||
from modoboa.lib.throttle import UserLesserDdosUser
|
||||
from modoboa.lib.viewsets import RevisionModelMixin
|
||||
from . import serializers
|
||||
|
||||
@@ -15,7 +15,12 @@ class RelayDomainViewSet(RevisionModelMixin, viewsets.ModelViewSet):
|
||||
|
||||
permission_classes = [IsAuthenticated, DjangoModelPermissions, ]
|
||||
serializer_class = serializers.RelayDomainSerializer
|
||||
throttle_classes = [UserDdosPerView, UserRateThrottle]
|
||||
|
||||
def get_throttles(self):
|
||||
if self.action:
|
||||
self.throttle_classes.append(UserLesserDdosUser)
|
||||
return super().get_throttles()
|
||||
|
||||
|
||||
def get_queryset(self):
|
||||
"""Filter queryset based on current user."""
|
||||
|
||||
@@ -187,12 +187,13 @@ MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
|
||||
|
||||
REST_FRAMEWORK = {
|
||||
'DEFAULT_THROTTLE_RATES': {
|
||||
'anon': '100/hour',
|
||||
'login': '3/minute',
|
||||
'ddos': '300/minute',
|
||||
'user': '400/minute',
|
||||
'ddos': '100/second',
|
||||
'ddos_lesser': '300/minute',
|
||||
'login': '10/minute',
|
||||
'password_recovery_request': '6/hour',
|
||||
'password_recovery_totp_check': '20/hour',
|
||||
'password_recovery_apply': '20/hour'
|
||||
'password_recovery_totp_check': '40/hour',
|
||||
'password_recovery_apply': '40/hour'
|
||||
},
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
'modoboa.core.drf_authentication.JWTAuthenticationWith2FA',
|
||||
|
||||
Reference in New Issue
Block a user