2016-10-12 05:13:32 +02:00
|
|
|
from django.http import HttpRequest, HttpResponse
|
|
|
|
from django.utils.translation import ugettext as _
|
2018-04-24 03:47:28 +02:00
|
|
|
from typing import List, Optional, Set
|
2016-10-12 05:13:32 +02:00
|
|
|
|
2019-06-18 16:43:22 +02:00
|
|
|
from zerver.decorator import require_realm_admin, require_member_or_admin
|
2019-02-15 19:09:25 +01:00
|
|
|
from zerver.lib.actions import do_invite_users, do_revoke_user_invite, \
|
|
|
|
do_revoke_multi_use_invite, do_resend_user_invite_email, \
|
2019-02-23 00:47:38 +01:00
|
|
|
do_get_user_invites, do_create_multiuse_invite_link
|
2016-10-12 05:13:32 +02:00
|
|
|
from zerver.lib.request import REQ, has_request_variables, JsonableError
|
2019-02-23 00:47:38 +01:00
|
|
|
from zerver.lib.response import json_success, json_error
|
2019-02-02 23:53:22 +01:00
|
|
|
from zerver.lib.streams import access_stream_by_id
|
2019-02-23 00:47:38 +01:00
|
|
|
from zerver.lib.validator import check_list, check_int
|
2019-02-15 19:09:25 +01:00
|
|
|
from zerver.models import PreregistrationUser, Stream, UserProfile, MultiuseInvite
|
2016-10-12 05:13:32 +02:00
|
|
|
|
|
|
|
import re
|
|
|
|
|
2019-06-18 16:43:22 +02:00
|
|
|
@require_member_or_admin
|
2016-10-12 05:13:32 +02:00
|
|
|
@has_request_variables
|
2017-12-06 19:39:15 +01:00
|
|
|
def invite_users_backend(request: HttpRequest, user_profile: UserProfile,
|
|
|
|
invitee_emails_raw: str=REQ("invitee_emails"),
|
2018-12-30 11:06:12 +01:00
|
|
|
invite_as: Optional[int]=REQ(
|
|
|
|
validator=check_int, default=PreregistrationUser.INVITE_AS['MEMBER']),
|
2018-12-22 05:41:54 +01:00
|
|
|
stream_ids: List[int]=REQ(validator=check_list(check_int)),
|
2017-12-06 19:39:15 +01:00
|
|
|
) -> HttpResponse:
|
2017-10-15 18:34:47 +02:00
|
|
|
|
2017-05-18 02:45:20 +02:00
|
|
|
if user_profile.realm.invite_by_admins_only and not user_profile.is_realm_admin:
|
2018-03-08 01:47:17 +01:00
|
|
|
return json_error(_("Must be an organization administrator"))
|
2018-12-30 11:06:12 +01:00
|
|
|
if invite_as not in PreregistrationUser.INVITE_AS.values():
|
|
|
|
return json_error(_("Must be invited as an valid type of user"))
|
|
|
|
if invite_as == PreregistrationUser.INVITE_AS['REALM_ADMIN'] and not user_profile.is_realm_admin:
|
2018-03-08 01:47:17 +01:00
|
|
|
return json_error(_("Must be an organization administrator"))
|
2016-10-12 05:13:32 +02:00
|
|
|
if not invitee_emails_raw:
|
|
|
|
return json_error(_("You must specify at least one email address."))
|
2018-12-22 05:41:54 +01:00
|
|
|
if not stream_ids:
|
|
|
|
return json_error(_("You must specify at least one stream for invitees to join."))
|
2016-10-12 05:13:32 +02:00
|
|
|
|
|
|
|
invitee_emails = get_invitee_emails_set(invitee_emails_raw)
|
|
|
|
|
|
|
|
# We unconditionally sub you to the notifications stream if it
|
|
|
|
# exists and is public.
|
2017-02-11 05:45:39 +01:00
|
|
|
notifications_stream = user_profile.realm.notifications_stream # type: Optional[Stream]
|
2016-10-12 05:13:32 +02:00
|
|
|
if notifications_stream and not notifications_stream.invite_only:
|
2018-12-22 05:41:54 +01:00
|
|
|
stream_ids.append(notifications_stream.id)
|
2016-10-12 05:13:32 +02:00
|
|
|
|
2017-05-17 22:10:59 +02:00
|
|
|
streams = [] # type: List[Stream]
|
2018-12-22 05:41:54 +01:00
|
|
|
for stream_id in stream_ids:
|
2017-01-30 03:09:04 +01:00
|
|
|
try:
|
2018-12-22 05:41:54 +01:00
|
|
|
(stream, recipient, sub) = access_stream_by_id(user_profile, stream_id)
|
2017-01-30 03:09:04 +01:00
|
|
|
except JsonableError:
|
2018-12-22 05:41:54 +01:00
|
|
|
return json_error(
|
2019-04-20 03:49:03 +02:00
|
|
|
_("Stream does not exist with id: {}. No invites were sent.").format(stream_id))
|
2016-10-12 05:13:32 +02:00
|
|
|
streams.append(stream)
|
|
|
|
|
2018-12-30 11:06:12 +01:00
|
|
|
do_invite_users(user_profile, invitee_emails, streams, invite_as)
|
2017-07-25 02:02:30 +02:00
|
|
|
return json_success()
|
2016-10-12 05:13:32 +02:00
|
|
|
|
2017-11-27 09:28:57 +01:00
|
|
|
def get_invitee_emails_set(invitee_emails_raw: str) -> Set[str]:
|
2016-10-12 05:13:32 +02:00
|
|
|
invitee_emails_list = set(re.split(r'[,\n]', invitee_emails_raw))
|
|
|
|
invitee_emails = set()
|
|
|
|
for email in invitee_emails_list:
|
|
|
|
is_email_with_name = re.search(r'<(?P<email>.*)>', email)
|
|
|
|
if is_email_with_name:
|
|
|
|
email = is_email_with_name.group('email')
|
|
|
|
invitee_emails.add(email.strip())
|
|
|
|
return invitee_emails
|
2017-10-21 03:15:12 +02:00
|
|
|
|
|
|
|
@require_realm_admin
|
2017-11-27 09:28:57 +01:00
|
|
|
def get_user_invites(request: HttpRequest, user_profile: UserProfile) -> HttpResponse:
|
2017-10-21 03:15:12 +02:00
|
|
|
all_users = do_get_user_invites(user_profile)
|
|
|
|
return json_success({'invites': all_users})
|
|
|
|
|
|
|
|
@require_realm_admin
|
|
|
|
@has_request_variables
|
2017-11-27 09:28:57 +01:00
|
|
|
def revoke_user_invite(request: HttpRequest, user_profile: UserProfile,
|
|
|
|
prereg_id: int) -> HttpResponse:
|
2017-12-05 20:01:55 +01:00
|
|
|
try:
|
|
|
|
prereg_user = PreregistrationUser.objects.get(id=prereg_id)
|
|
|
|
except PreregistrationUser.DoesNotExist:
|
2017-12-05 20:05:17 +01:00
|
|
|
raise JsonableError(_("No such invitation"))
|
2017-12-05 20:01:55 +01:00
|
|
|
|
|
|
|
if prereg_user.referred_by.realm != user_profile.realm:
|
2017-12-05 20:05:17 +01:00
|
|
|
raise JsonableError(_("No such invitation"))
|
2017-12-05 20:01:55 +01:00
|
|
|
|
|
|
|
do_revoke_user_invite(prereg_user)
|
2017-10-21 03:15:12 +02:00
|
|
|
return json_success()
|
|
|
|
|
2019-02-15 19:09:25 +01:00
|
|
|
@require_realm_admin
|
|
|
|
@has_request_variables
|
|
|
|
def revoke_multiuse_invite(request: HttpRequest, user_profile: UserProfile,
|
|
|
|
invite_id: int) -> HttpResponse:
|
|
|
|
|
|
|
|
try:
|
|
|
|
invite = MultiuseInvite.objects.get(id=invite_id)
|
|
|
|
except MultiuseInvite.DoesNotExist:
|
|
|
|
raise JsonableError(_("No such invitation"))
|
|
|
|
|
|
|
|
if invite.realm != user_profile.realm:
|
|
|
|
raise JsonableError(_("No such invitation"))
|
|
|
|
|
|
|
|
do_revoke_multi_use_invite(invite)
|
|
|
|
return json_success()
|
|
|
|
|
2017-10-21 03:15:12 +02:00
|
|
|
@require_realm_admin
|
|
|
|
@has_request_variables
|
2017-11-27 09:28:57 +01:00
|
|
|
def resend_user_invite_email(request: HttpRequest, user_profile: UserProfile,
|
|
|
|
prereg_id: int) -> HttpResponse:
|
2017-12-05 20:01:55 +01:00
|
|
|
try:
|
|
|
|
prereg_user = PreregistrationUser.objects.get(id=prereg_id)
|
|
|
|
except PreregistrationUser.DoesNotExist:
|
2017-12-05 20:05:17 +01:00
|
|
|
raise JsonableError(_("No such invitation"))
|
2017-12-05 20:01:55 +01:00
|
|
|
|
2019-03-21 23:37:15 +01:00
|
|
|
# Structurally, any invitation the user can actually access should
|
|
|
|
# have a referred_by set for the user who created it.
|
|
|
|
if prereg_user.referred_by is None or prereg_user.referred_by.realm != user_profile.realm:
|
2017-12-05 20:05:17 +01:00
|
|
|
raise JsonableError(_("No such invitation"))
|
2017-12-05 20:01:55 +01:00
|
|
|
|
|
|
|
timestamp = do_resend_user_invite_email(prereg_user)
|
2017-10-21 03:15:12 +02:00
|
|
|
return json_success({'timestamp': timestamp})
|
2018-03-02 12:27:57 +01:00
|
|
|
|
2018-06-16 15:32:59 +02:00
|
|
|
@require_realm_admin
|
2018-03-02 12:27:57 +01:00
|
|
|
@has_request_variables
|
2019-02-06 22:57:14 +01:00
|
|
|
def generate_multiuse_invite_backend(
|
|
|
|
request: HttpRequest, user_profile: UserProfile,
|
|
|
|
invite_as: int=REQ(validator=check_int, default=PreregistrationUser.INVITE_AS['MEMBER']),
|
|
|
|
stream_ids: List[int]=REQ(validator=check_list(check_int), default=[])) -> HttpResponse:
|
2018-03-02 12:27:57 +01:00
|
|
|
streams = []
|
|
|
|
for stream_id in stream_ids:
|
|
|
|
try:
|
|
|
|
(stream, recipient, sub) = access_stream_by_id(user_profile, stream_id)
|
|
|
|
except JsonableError:
|
2019-04-20 03:49:03 +02:00
|
|
|
return json_error(_("Invalid stream id {}. No invites were sent.").format(stream_id))
|
2018-03-02 12:27:57 +01:00
|
|
|
streams.append(stream)
|
|
|
|
|
2019-02-06 22:57:14 +01:00
|
|
|
invite_link = do_create_multiuse_invite_link(user_profile, invite_as, streams)
|
2018-03-02 12:27:57 +01:00
|
|
|
return json_success({'invite_link': invite_link})
|