feat: rate limiting and Redis caching setup
Added rate limiting to the SendLoginEmailView to prevent abuse by applying the `ratelimit` decorator. Configured Redis as a cache backend based on settings from the configuration file. Updated dependencies to include `django-ratelimit`, `redis`, and `django-redis` packages to support these enhancements. These changes improve the security and performance of the application by limiting login email attempts and using Redis for caching.
This commit is contained in:
parent
4f407c2d8a
commit
4f62f6eff2
3 changed files with 21 additions and 0 deletions
|
@ -8,6 +8,7 @@ from django.views.generic import FormView, View
|
||||||
from django.contrib.auth.tokens import default_token_generator
|
from django.contrib.auth.tokens import default_token_generator
|
||||||
from django.contrib.auth import logout
|
from django.contrib.auth import logout
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
|
from django.utils.decorators import method_decorator
|
||||||
|
|
||||||
from rest_framework.authtoken.models import Token
|
from rest_framework.authtoken.models import Token
|
||||||
from rest_framework.authtoken.views import ObtainAuthToken
|
from rest_framework.authtoken.views import ObtainAuthToken
|
||||||
|
@ -15,11 +16,14 @@ from rest_framework.response import Response
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
|
||||||
|
from django_ratelimit.decorators import ratelimit
|
||||||
|
|
||||||
from .forms import EmailForm, GenerateTokenForm
|
from .forms import EmailForm, GenerateTokenForm
|
||||||
|
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
|
||||||
|
|
||||||
|
@method_decorator(ratelimit(key="ip", rate="1/m", method="POST"), name="dispatch")
|
||||||
class SendLoginEmailView(FormView):
|
class SendLoginEmailView(FormView):
|
||||||
template_name = "accounts/send_login_email.html"
|
template_name = "accounts/send_login_email.html"
|
||||||
form_class = EmailForm
|
form_class = EmailForm
|
||||||
|
|
|
@ -188,3 +188,17 @@ else:
|
||||||
|
|
||||||
EMAIL_SUBJECT_PREFIX = "[FreeDOI] "
|
EMAIL_SUBJECT_PREFIX = "[FreeDOI] "
|
||||||
DEFAULT_FROM_EMAIL = "noreply@freedoi.org"
|
DEFAULT_FROM_EMAIL = "noreply@freedoi.org"
|
||||||
|
|
||||||
|
# Redis
|
||||||
|
|
||||||
|
if (redis_host := CONFIG.get("Redis", "Host", fallback=None)) is not None:
|
||||||
|
CACHES = {
|
||||||
|
"default": {
|
||||||
|
"BACKEND": "django_redis.cache.RedisCache",
|
||||||
|
"LOCATION": f"redis://{redis_host}:{CONFIG.getint('Redis', 'Port', fallback=6379)}/1",
|
||||||
|
"OPTIONS": {
|
||||||
|
"CLIENT_CLASS": "django_redis.client.DefaultClient",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,9 @@ django-crispy-forms = "*"
|
||||||
crispy-bootstrap5 = "*"
|
crispy-bootstrap5 = "*"
|
||||||
django-two-factor-auth = "*"
|
django-two-factor-auth = "*"
|
||||||
phonenumbers = "*"
|
phonenumbers = "*"
|
||||||
|
django-ratelimit = "*"
|
||||||
|
redis = "*"
|
||||||
|
django-redis = "*"
|
||||||
|
|
||||||
[tool.poetry.group.mysql.dependencies]
|
[tool.poetry.group.mysql.dependencies]
|
||||||
mysqlclient = "*"
|
mysqlclient = "*"
|
||||||
|
|
Loading…
Reference in a new issue