Files
zulip/zerver/signals.py
Tim Abbott 05c190a97c Fix new-login emails for iOS not identifying OS correctly.
Previously, we were only checking for common strings in iOS browsers,
not for the explicit string that we use with the Zulip app.
2017-07-07 13:34:25 -07:00

92 lines
3.2 KiB
Python

from __future__ import absolute_import
from django.dispatch import receiver
from django.contrib.auth.signals import user_logged_in
from django.conf import settings
from django.template import loader
from django.utils.timezone import get_current_timezone_name as timezone_get_current_timezone_name
from django.utils.timezone import now as timezone_now
from typing import Any, Dict, Optional
from zerver.lib.send_email import send_email_to_user
from zerver.models import UserProfile
def get_device_browser(user_agent):
# type: (str) -> Optional[str]
user_agent = user_agent.lower()
if "zulip" in user_agent:
return "Zulip"
elif "edge" in user_agent:
return "Edge"
elif "opera" in user_agent or "opr/" in user_agent:
return "Opera"
elif "chrome" in user_agent and "chromium" not in user_agent:
return 'Chrome'
elif "firefox" in user_agent and "seamonkey" not in user_agent and "chrome" not in user_agent:
return "Firefox"
elif "chromium" in user_agent:
return "Chromium"
elif "safari" in user_agent and "chrome" not in user_agent and "chromium" not in user_agent:
return "Safari"
elif "msie" in user_agent or "trident" in user_agent:
return "Internet Explorer"
else:
return None
def get_device_os(user_agent):
# type: (str) -> Optional[str]
user_agent = user_agent.lower()
if "windows" in user_agent:
return "Windows"
elif "macintosh" in user_agent:
return "MacOS"
elif "linux" in user_agent and "android" not in user_agent:
return "Linux"
elif "android" in user_agent:
return "Android"
elif "ios" in user_agent:
return "iOS"
elif "like mac os x" in user_agent:
return "iOS"
else:
return None
@receiver(user_logged_in, dispatch_uid="only_on_login")
def email_on_new_login(sender, user, request, **kwargs):
# type: (Any, UserProfile, Any, **Any) -> None
# We import here to minimize the dependencies of this module,
# since it runs as part of `manage.py` initialization
from zerver.context_processors import common_context
if not settings.SEND_LOGIN_EMAILS:
return
if request:
# Login emails are for returning users, not new registrations.
# Determine if login request was from new registration.
path = request.META.get('PATH_INFO', None)
if path:
if path == "/accounts/register/":
return
login_time = timezone_now().strftime('%A, %B %d, %Y at %I:%M%p ') + \
timezone_get_current_timezone_name()
user_agent = request.META.get('HTTP_USER_AGENT', "").lower()
device_browser = get_device_browser(user_agent)
device_os = get_device_os(user_agent)
device_ip = request.META.get('REMOTE_ADDR') or "Uknown IP address"
device_info = {"device_browser": device_browser,
"device_os": device_os,
"device_ip": device_ip,
"login_time": login_time
}
context = common_context(user)
context['device_info'] = device_info
context['user'] = user
send_email_to_user('zerver/emails/notify_new_login', user, context=context)