Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions apps/api/plane/authentication/views/app/email.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# Module imports
from plane.authentication.provider.credentials.email import EmailProvider
from plane.authentication.utils.login import user_login
from plane.authentication.rate_limit import authentication_throttle_allows
from plane.license.models import Instance
from plane.authentication.utils.host import base_host
from plane.authentication.utils.redirection_path import get_redirection_path
Expand All @@ -26,6 +27,23 @@
class SignInAuthEndpoint(View):
def post(self, request):
next_path = request.POST.get("next_path")

# Rate-limit all password auth attempts before any DB access.
# authentication_throttle_allows() applies the same AuthenticationThrottle
# that magic-code views use (default: 10/minute, configurable via
# AUTHENTICATION_RATE_LIMIT env var).
if not authentication_throttle_allows(request):
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES["RATE_LIMIT_EXCEEDED"],
error_message="RATE_LIMIT_EXCEEDED",
)
url = get_safe_redirect_url(
base_url=base_host(request=request, is_app=True),
next_path=next_path,
params=exc.get_error_dict(),
)
return HttpResponseRedirect(url)

# Check instance configuration
instance = Instance.objects.first()
if instance is None or not instance.is_setup_done:
Expand Down Expand Up @@ -135,6 +153,20 @@ def post(self, request):
class SignUpAuthEndpoint(View):
def post(self, request):
next_path = request.POST.get("next_path")

# Rate-limit before any DB access (same throttle as sign-in / magic-code).
if not authentication_throttle_allows(request):
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES["RATE_LIMIT_EXCEEDED"],
error_message="RATE_LIMIT_EXCEEDED",
)
url = get_safe_redirect_url(
base_url=base_host(request=request, is_app=True),
next_path=next_path,
params=exc.get_error_dict(),
)
return HttpResponseRedirect(url)

# Check instance configuration
instance = Instance.objects.first()
if instance is None or not instance.is_setup_done:
Expand Down
29 changes: 29 additions & 0 deletions apps/api/plane/authentication/views/space/email.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# Module imports
from plane.authentication.provider.credentials.email import EmailProvider
from plane.authentication.utils.login import user_login
from plane.authentication.rate_limit import authentication_throttle_allows
from plane.license.models import Instance
from plane.authentication.utils.host import base_host
from plane.db.models import User
Expand All @@ -25,6 +26,20 @@
class SignInAuthSpaceEndpoint(View):
def post(self, request):
next_path = request.POST.get("next_path")

# Rate-limit before any DB access.
if not authentication_throttle_allows(request):
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES["RATE_LIMIT_EXCEEDED"],
error_message="RATE_LIMIT_EXCEEDED",
)
url = get_safe_redirect_url(
base_url=base_host(request=request, is_space=True),
next_path=next_path,
params=exc.get_error_dict(),
)
return HttpResponseRedirect(url)

# Check instance configuration
instance = Instance.objects.first()
if instance is None or not instance.is_setup_done:
Expand Down Expand Up @@ -110,6 +125,20 @@ def post(self, request):
class SignUpAuthSpaceEndpoint(View):
def post(self, request):
next_path = request.POST.get("next_path")

# Rate-limit before any DB access.
if not authentication_throttle_allows(request):
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES["RATE_LIMIT_EXCEEDED"],
error_message="RATE_LIMIT_EXCEEDED",
)
url = get_safe_redirect_url(
base_url=base_host(request=request, is_space=True),
next_path=next_path,
params=exc.get_error_dict(),
)
return HttpResponseRedirect(url)

# Check instance configuration
instance = Instance.objects.first()
if instance is None or not instance.is_setup_done:
Expand Down
Loading