WIP: active-sessions #93586

Closed
Oleg-Komarov wants to merge 3 commits from active-sessions into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
3 changed files with 62 additions and 5 deletions
Showing only changes of commit b52564fb36 - Show all commits

View File

@ -257,3 +257,42 @@ def check_verification_payload(
log.debug("verification OK") log.debug("verification OK")
return VerificationResult.OK, payload return VerificationResult.OK, payload
def send_new_user_session(session):
if not hasattr(session, 'user'):
log.error('programming error: called for a session without a user')
return False
user = session.user
# sending only a text/plain email to reduce the room for look-alike phishing emails
email_body_txt, subject = construct_new_user_session(session)
email = user.email
try:
send_mail(
subject,
message=email_body_txt,
from_email=None, # just use the configured default From-address.
recipient_list=[email],
fail_silently=False,
)
except (smtplib.SMTPException, OSError):
log.exception("failed to send a new user session email for account %s", user.pk)
return False
log.info("sent a new user session email for account %s", user.pk)
return True
def construct_new_user_session(session):
context = {
"session": session,
"user": session.user,
"subject": "Blender ID new sign-in",
}
email_body_txt = loader.render_to_string(
"bid_main/emails/new_user_session.txt", context
)
return email_body_txt, context["subject"]

View File

@ -6,7 +6,7 @@ from django.db.models import F
from django.db.models.signals import m2m_changed, post_delete from django.db.models.signals import m2m_changed, post_delete
from django.dispatch import receiver from django.dispatch import receiver
from . import models from . import email, models
import bid_main.utils as utils import bid_main.utils as utils
import bid_main.file_utils import bid_main.file_utils
@ -19,8 +19,8 @@ def log_exception(sender, **kwargs):
@receiver(user_logged_in) @receiver(user_logged_in)
def update_user_for_login(sender, request, user, **kwargs): def process_new_login(sender, request, user, **kwargs):
"""Updates user fields upon login. """Updates user fields upon login. Sends an email if IP is new.
Only saves specific fields, so that the webhook trigger knows what changed. Only saves specific fields, so that the webhook trigger knows what changed.
""" """
@ -33,9 +33,11 @@ def update_user_for_login(sender, request, user, **kwargs):
if request_ip and user.current_login_ip != request_ip: if request_ip and user.current_login_ip != request_ip:
user.last_login_ip = F("current_login_ip") user.last_login_ip = F("current_login_ip")
user.current_login_ip = request_ip user.current_login_ip = request_ip
fields.update({"last_login_ip", "current_login_ip"}) fields.update({"last_login_ip", "current_login_ip"})
try:
email.send_new_user_session(request.session.create_model_instance({}))
except Exception:
log.exception('failed to send a new user session email')
user.save(update_fields=fields) user.save(update_fields=fields)

View File

@ -0,0 +1,16 @@
{% autoescape off %}
Dear {{ user.full_name|default:user.email }}!
A new sign-in for your Blender ID account {{ user.email }}
IP address: {{ session.ip }}
Location: ({{ session.location }})
Device: {{ session.device }}
If this was you, you can ignore this message.
If this wasn't you, please change or reset your password.
--
Kind regards,
The Blender Web Team
{% endautoescape %}