mirror of
https://github.com/zulip/zulip.git
synced 2025-11-11 01:16:19 +00:00
This reimplements our Zoom video call integration to use an OAuth application. In addition to providing a cleaner setup experience, especially on zulipchat.com where the server administrators can have done the app registration already, it also fixes the limitation of the previous integration that it could only have one call active at a time when set up with typical Zoom API keys. Fixes #11672. Co-authored-by: Marco Burstein <marco@marco.how> Co-authored-by: Tim Abbott <tabbott@zulipchat.com> Signed-off-by: Anders Kaseorg <andersk@mit.edu>
111 lines
4.2 KiB
Python
111 lines
4.2 KiB
Python
from typing import Any, Optional
|
|
|
|
from django.conf import settings
|
|
from django.contrib.auth.signals import user_logged_in, user_logged_out
|
|
from django.dispatch import receiver
|
|
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 django.utils.translation import ugettext as _
|
|
|
|
from confirmation.models import one_click_unsubscribe_link
|
|
from zerver.lib.actions import do_set_zoom_token
|
|
from zerver.lib.queue import queue_json_publish
|
|
from zerver.lib.send_email import FromAddress
|
|
from zerver.models import UserProfile
|
|
from zerver.lib.timezone import get_timezone
|
|
|
|
JUST_CREATED_THRESHOLD = 60
|
|
|
|
def get_device_browser(user_agent: 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 or "crios" 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: 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"
|
|
elif " cros " in user_agent:
|
|
return "ChromeOS"
|
|
else:
|
|
return None
|
|
|
|
|
|
@receiver(user_logged_in, dispatch_uid="only_on_login")
|
|
def email_on_new_login(sender: Any, user: UserProfile, request: Any, **kwargs: Any) -> None:
|
|
if not user.enable_login_emails:
|
|
return
|
|
# 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:
|
|
# If the user's account was just created, avoid sending an email.
|
|
if (timezone_now() - user.date_joined).total_seconds() <= JUST_CREATED_THRESHOLD:
|
|
return
|
|
|
|
user_agent = request.META.get('HTTP_USER_AGENT', "").lower()
|
|
|
|
context = common_context(user)
|
|
context['user_email'] = user.delivery_email
|
|
user_tz = user.timezone
|
|
if user_tz == '':
|
|
user_tz = timezone_get_current_timezone_name()
|
|
local_time = timezone_now().astimezone(get_timezone(user_tz))
|
|
if user.twenty_four_hour_time:
|
|
hhmm_string = local_time.strftime('%H:%M')
|
|
else:
|
|
hhmm_string = local_time.strftime('%I:%M%p')
|
|
context['login_time'] = local_time.strftime('%A, %B %d, %Y at {} %Z'.format(hhmm_string))
|
|
context['device_ip'] = request.META.get('REMOTE_ADDR') or _("Unknown IP address")
|
|
context['device_os'] = get_device_os(user_agent) or _("an unknown operating system")
|
|
context['device_browser'] = get_device_browser(user_agent) or _("An unknown browser")
|
|
context['unsubscribe_link'] = one_click_unsubscribe_link(user, 'login')
|
|
|
|
email_dict = {
|
|
'template_prefix': 'zerver/emails/notify_new_login',
|
|
'to_user_ids': [user.id],
|
|
'from_name': FromAddress.security_email_from_name(user_profile=user),
|
|
'from_address': FromAddress.NOREPLY,
|
|
'context': context}
|
|
queue_json_publish("email_senders", email_dict)
|
|
|
|
|
|
@receiver(user_logged_out)
|
|
def clear_zoom_token_on_logout(
|
|
sender: object, *, user: Optional[UserProfile], **kwargs: object
|
|
) -> None:
|
|
if user is not None and user.zoom_token is not None:
|
|
do_set_zoom_token(user, None)
|