Skip to content

Commit

Permalink
Minor refactoring for clarity
Browse files Browse the repository at this point in the history
  • Loading branch information
Hugh Enxing committed Aug 22, 2023
1 parent 10bbd50 commit 1bac2bd
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 42 deletions.
57 changes: 30 additions & 27 deletions api/main/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,11 @@ def authenticate(self, request, username=None, password=None, **kwargs):
user.save()
lockout_lifted = user.last_failed_login + LOCKOUT_TIME
time_left = lockout_lifted - now
msg = f" *SECURITY ALERT:* Attempt to login during lockout"
msg += f" User={user}/{user.id}"
msg += f" Attempt count = {user.failed_login_count}"
msg += f" Lockout will be lifted in '{time_left}' at '{lockout_lifted}'"
msg = (
f" *SECURITY ALERT:* Attempt to login during lockout: User={user}/{user.id}, "
f" Attempt count = {user.failed_login_count}. Lockout will be lifted in "
f"'{time_left}' at '{lockout_lifted}'"
)
Notify.notify_admin_msg(msg)
# Run the default password hasher once to reduce the timing
# difference (#20760).
Expand All @@ -59,30 +60,32 @@ def authenticate(self, request, username=None, password=None, **kwargs):
if user.check_password(password) and self.user_can_authenticate(user):
user.last_login = datetime.now(timezone.utc)
if user.failed_login_count >= LOCKOUT_LIMIT:
msg = "Login proceeded after lock expiry"
msg += f" User={user}/{user.id}"
msg = "Login proceeded after lock expiry User={user}/{user.id}"
Notify.notify_admin_msg(msg)
user.failed_login_count = 0
user.save()
return user
else:
user.last_failed_login = datetime.now(timezone.utc)
user.failed_login_count += 1
user.save()
if user.failed_login_count >= LOCKOUT_LIMIT:
msg = f"*SECURITY ALERT:* Bad Login Attempt for {user}/{user.id}"
msg += f" Attempt count = {user.failed_login_count}"
Notify.notify_admin_msg(msg)
# Send an email if the failed login count has been reached.
if (user.failed_login_count == LOCKOUT_LIMIT) and settings.TATOR_EMAIL_ENABLED:
get_email_service().email(
sender=settings.TATOR_EMAIL_SENDER,
recipients=[user.email],
title=f"Tator account has been locked",
text="This message is to notify you that your Tator account (username "
f"{user.username}) has been locked due to {LOCKOUT_LIMIT} failed logins. "
"Your account will be unlocked automatically after 10 minutes, or you "
"can unlock your account now by resetting your password. To reset your "
"password, follow the procedure described here:\n\n"
"https://tator.io/tutorials/2021-06-11-reset-your-password/",
)

user.last_failed_login = datetime.now(timezone.utc)
user.failed_login_count += 1
user.save()
if user.failed_login_count >= LOCKOUT_LIMIT:
msg = (
f"*SECURITY ALERT:* Bad Login Attempt for {user}/{user.id}. Attempt count = "
f"{user.failed_login_count}"
)
Notify.notify_admin_msg(msg)
# Send an email if the failed login count has been reached.
email_service = get_email_service()
if user.failed_login_count == LOCKOUT_LIMIT and email_service:
email_service.email(
sender=settings.TATOR_EMAIL_SENDER,
recipients=[user.email],
title=f"Tator account has been locked",
text="This message is to notify you that your Tator account (username "
f"{user.username}) has been locked due to {LOCKOUT_LIMIT} failed logins. "
"Your account will be unlocked automatically after 10 minutes, or you "
"can unlock your account now by resetting your password. To reset your "
"password, follow the procedure described here:\n\n"
"https://tator.io/tutorials/2021-06-11-reset-your-password/",
)
30 changes: 15 additions & 15 deletions api/main/rest/password_reset.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import uuid
import os
import logging
import uuid

from django.db import transaction
from django.conf import settings
from django.http import Http404

from ..models import PasswordReset
from ..models import User
from ..schema import PasswordResetListSchema
from ..mail import get_email_service
from ..models import PasswordReset, User
from ..schema import PasswordResetListSchema

from ._base_views import BaseListView

Expand All @@ -31,17 +27,21 @@ def _post(self, params):
raise RuntimeError(f"Email {email} is in use by multiple users!")
user = users[0]
reset = PasswordReset(user=user, reset_token=uuid.uuid1())
url = f"{os.getenv('MAIN_HOST')}/password-reset?reset_token={reset.reset_token}&user={user.id}"
if settings.TATOR_EMAIL_ENABLED:
get_email_service().email(
url = f"{settings.PROTO}://{settings.MAIN_HOST}/password-reset?reset_token={reset.reset_token}&user={user.id}"
email_service = get_email_service()
if email_service:
text = (
f"A password reset has been requested for this email address ({email}). If you did "
f"not initiate the reset this message can be ignored. To reset your password, "
f"please visit: \n\n{url}\n\nThis URL will expire in 24 hours."
)
failure_msg = f"Unable to send email to {email}! Password reset creation failed."
email_service.email(
sender=settings.TATOR_EMAIL_SENDER,
recipients=[email],
title=f"Tator password reset",
text=f"A password reset has been requested for this email address ({email}). "
f"If you did not initiate the reset this message can be ignored. "
f"To reset your password, please visit: \n\n{url}\n\n"
"This URL will expire in 24 hours.",
raise_on_failure=f"Unable to send email to {email}! Password reset creation failed.",
text=text,
raise_on_failure=failure_msg,
)
else:
raise RuntimeError(
Expand Down

0 comments on commit 1bac2bd

Please sign in to comment.