Ejemplo n.º 1
0
    def consume(self, data: Mapping[str, Any]) -> None:
        if "email" in data:
            # When upgrading from a version up through 1.7.1, there may be
            # existing items in the queue with `email` instead of `prereg_id`.
            invitee = PreregistrationUser.objects.filter(
                email__iexact=data["email"].strip()).latest("invited_at")
        else:
            invitee = PreregistrationUser.objects.filter(id=data["prereg_id"]).first()
            if invitee is None:
                # The invitation could have been revoked
                return

        referrer = get_user_profile_by_id(data["referrer_id"])
        logger.info("Sending invitation for realm %s to %s" % (referrer.realm.string_id, invitee.email))
        do_send_confirmation_email(invitee, referrer)

        # queue invitation reminder for two days from now.
        link = create_confirmation_link(invitee, referrer.realm.host, Confirmation.INVITATION)
        context = common_context(referrer)
        context.update({
            'activate_url': link,
            'referrer_name': referrer.full_name,
            'referrer_email': referrer.email,
            'referrer_realm_name': referrer.realm.name,
        })
        send_future_email(
            "zerver/emails/invitation_reminder",
            referrer.realm,
            to_emails=[invitee.email],
            from_address=FromAddress.tokenized_no_reply_address(),
            language=referrer.realm.default_language,
            context=context,
            delay=datetime.timedelta(days=2))
Ejemplo n.º 2
0
def maybe_send_to_registration(request, email, full_name='', password_required=True):
    # type: (HttpRequest, Text, Text, bool) -> HttpResponse
    form = HomepageForm({'email': email}, realm=get_realm_from_request(request))
    request.verified_email = None
    if form.is_valid():
        # Construct a PreregistrationUser object and send the user over to
        # the confirmation view.
        prereg_user = None
        if settings.ONLY_SSO:
            try:
                prereg_user = PreregistrationUser.objects.filter(email__iexact=email).latest("invited_at")
            except PreregistrationUser.DoesNotExist:
                prereg_user = create_preregistration_user(email, request,
                                                          password_required=password_required)
        else:
            prereg_user = create_preregistration_user(email, request,
                                                      password_required=password_required)

        return redirect("".join((
            create_confirmation_link(prereg_user, request.get_host(), Confirmation.USER_REGISTRATION),
            '?full_name=',
            # urllib does not handle Unicode, so coerece to encoded byte string
            # Explanation: http://stackoverflow.com/a/5605354/90777
            urllib.parse.quote_plus(full_name.encode('utf8')))))
    else:
        url = reverse('register')
        return render(request,
                      'zerver/accounts_home.html',
                      context={'form': form, 'current_url': lambda: url},
                      )
Ejemplo n.º 3
0
    def handle(self, *args: Any, **options: Any) -> None:
        duplicates = False
        realm = self.get_realm(options)
        assert realm is not None  # Should be ensured by parser

        if not options['emails']:
            self.print_help("./manage.py", "generate_invite_links")
            exit(1)

        for email in options['emails']:
            try:
                self.get_user(email, realm)
                print(email + ": There is already a user registered with that address.")
                duplicates = True
                continue
            except CommandError:
                pass

        if duplicates:
            return

        for email in options['emails']:
            try:
                email_allowed_for_realm(email, realm)
            except DomainNotAllowedForRealmError:
                if not options["force"]:
                    print("You've asked to add an external user '%s' to a closed realm '%s'." % (
                        email, realm.string_id))
                    print("Are you sure? To do this, pass --force.")
                    exit(1)

            prereg_user = PreregistrationUser(email=email, realm=realm)
            prereg_user.save()
            print(email + ": " + create_confirmation_link(prereg_user, realm.host,
                                                          Confirmation.INVITATION))
Ejemplo n.º 4
0
def one_click_unsubscribe_link(user_profile: UserProfile, email_type: str) -> str:
    """
    Generate a unique link that a logged-out user can visit to unsubscribe from
    Zulip e-mails without having to first log in.
    """
    return create_confirmation_link(user_profile, user_profile.realm.host,
                                    Confirmation.UNSUBSCRIBE,
                                    url_args = {'email_type': email_type})
Ejemplo n.º 5
0
 def test_realm_reactivation_link(self) -> None:
     realm = get_realm('zulip')
     do_deactivate_realm(realm)
     self.assertTrue(realm.deactivated)
     confirmation_url = create_confirmation_link(realm, realm.host, Confirmation.REALM_REACTIVATION)
     response = self.client_get(confirmation_url)
     self.assert_in_success_response(['Your organization has been successfully reactivated'], response)
     realm = get_realm('zulip')
     self.assertFalse(realm.deactivated)
Ejemplo n.º 6
0
def maybe_send_to_registration(request: HttpRequest, email: str, full_name: str='',
                               is_signup: bool=False, password_required: bool=True,
                               multiuse_object_key: str='') -> HttpResponse:
    realm = get_realm(get_subdomain(request))
    from_multiuse_invite = False
    multiuse_obj = None
    streams_to_subscribe = None
    invited_as = PreregistrationUser.INVITE_AS['MEMBER']
    if multiuse_object_key:
        from_multiuse_invite = True
        multiuse_obj = Confirmation.objects.get(confirmation_key=multiuse_object_key).content_object
        realm = multiuse_obj.realm
        streams_to_subscribe = multiuse_obj.streams.all()
        invited_as = multiuse_obj.invited_as

    form = HomepageForm({'email': email}, realm=realm, from_multiuse_invite=from_multiuse_invite)
    if form.is_valid():
        # Construct a PreregistrationUser object and send the user over to
        # the confirmation view.
        prereg_user = None
        if settings.ONLY_SSO:
            try:
                prereg_user = PreregistrationUser.objects.filter(
                    email__iexact=email, realm=realm).latest("invited_at")
            except PreregistrationUser.DoesNotExist:
                prereg_user = create_preregistration_user(email, request,
                                                          password_required=password_required)
        else:
            prereg_user = create_preregistration_user(email, request,
                                                      password_required=password_required)

        if multiuse_object_key:
            request.session.modified = True
            if streams_to_subscribe is not None:
                prereg_user.streams.set(streams_to_subscribe)
            prereg_user.invited_as = invited_as
            prereg_user.save()

        confirmation_link = create_confirmation_link(prereg_user, request.get_host(),
                                                     Confirmation.USER_REGISTRATION)
        if is_signup:
            return redirect(confirmation_link)

        context = {'email': email,
                   'continue_link': confirmation_link,
                   'full_name': full_name}
        return render(request,
                      'zerver/confirm_continue_registration.html',
                      context=context)
    else:
        url = reverse('register')
        return render(request,
                      'zerver/accounts_home.html',
                      context={'form': form, 'current_url': lambda: url,
                               'from_multiuse_invite': from_multiuse_invite,
                               'multiuse_object_key': multiuse_object_key},
                      )
Ejemplo n.º 7
0
def maybe_send_to_registration(request: HttpRequest, email: str, full_name: str='',
                               is_signup: bool=False, password_required: bool=True) -> HttpResponse:
    realm = get_realm(get_subdomain(request))
    from_multiuse_invite = False
    multiuse_obj = None
    streams_to_subscribe = None
    multiuse_object_key = request.session.get("multiuse_object_key", None)
    if multiuse_object_key is not None:
        from_multiuse_invite = True
        multiuse_obj = Confirmation.objects.get(confirmation_key=multiuse_object_key).content_object
        realm = multiuse_obj.realm
        streams_to_subscribe = multiuse_obj.streams.all()

    form = HomepageForm({'email': email}, realm=realm, from_multiuse_invite=from_multiuse_invite)
    if form.is_valid():
        # Construct a PreregistrationUser object and send the user over to
        # the confirmation view.
        prereg_user = None
        if settings.ONLY_SSO:
            try:
                prereg_user = PreregistrationUser.objects.filter(
                    email__iexact=email, realm=realm).latest("invited_at")
            except PreregistrationUser.DoesNotExist:
                prereg_user = create_preregistration_user(email, request,
                                                          password_required=password_required)
        else:
            prereg_user = create_preregistration_user(email, request,
                                                      password_required=password_required)

        if multiuse_object_key is not None:
            del request.session["multiuse_object_key"]
            request.session.modified = True
            if streams_to_subscribe is not None:
                prereg_user.streams.set(streams_to_subscribe)

        confirmation_link = "".join((
            create_confirmation_link(prereg_user, request.get_host(), Confirmation.USER_REGISTRATION),
            '?full_name=',
            # urllib does not handle Unicode, so coerece to encoded byte string
            # Explanation: http://stackoverflow.com/a/5605354/90777
            urllib.parse.quote_plus(full_name.encode('utf8'))))
        if is_signup:
            return redirect(confirmation_link)

        context = {'email': email,
                   'continue_link': confirmation_link}
        return render(request,
                      'zerver/confirm_continue_registration.html',
                      context=context)
    else:
        url = reverse('register')
        return render(request,
                      'zerver/accounts_home.html',
                      context={'form': form, 'current_url': lambda: url,
                               'from_multiuse_invite': from_multiuse_invite},
                      )
Ejemplo n.º 8
0
def send_registration_completion_email(email, request, realm_creation=False):
    # type: (str, HttpRequest, bool) -> None
    """
    Send an email with a confirmation link to the provided e-mail so the user
    can complete their registration.
    """
    prereg_user = create_preregistration_user(email, request, realm_creation)
    activation_url = create_confirmation_link(prereg_user, request.get_host(), Confirmation.USER_REGISTRATION)
    send_email('zerver/emails/confirm_registration', to_email=email, from_address=FromAddress.NOREPLY,
               context={'activate_url': activation_url})
    if settings.DEVELOPMENT and realm_creation:
        request.session['confirmation_key'] = {'confirmation_key': activation_url.split('/')[-1]}
Ejemplo n.º 9
0
def prepare_activation_url(email: str, request: HttpRequest,
                           realm_creation: bool=False,
                           streams: Optional[List[Stream]]=None) -> str:
    """
    Send an email with a confirmation link to the provided e-mail so the user
    can complete their registration.
    """
    prereg_user = create_preregistration_user(email, request, realm_creation)

    if streams is not None:
        prereg_user.streams.set(streams)

    confirmation_type = Confirmation.USER_REGISTRATION
    if realm_creation:
        confirmation_type = Confirmation.REALM_CREATION

    activation_url = create_confirmation_link(prereg_user, request.get_host(), confirmation_type)
    if settings.DEVELOPMENT and realm_creation:
        request.session['confirmation_key'] = {'confirmation_key': activation_url.split('/')[-1]}
    return activation_url
    def handle(self, *args: Any, **options: Any) -> None:
        realm = self.get_realm(options)
        assert realm is not None  # Should be ensured by parser

        streams = []
        if options["streams"]:
            stream_names = set([stream.strip() for stream in options["streams"].split(",")])

            for stream_name in set(stream_names):
                stream, _ = create_stream_if_needed(realm, stream_name)
                streams.append(stream)

        referred_by = self.get_user(options['referred_by'], realm)
        invite = MultiuseInvite.objects.create(realm=realm, referred_by=referred_by)

        if streams:
            invite.streams = streams
            invite.save()

        invite_link = create_confirmation_link(invite, realm.host, Confirmation.MULTIUSE_INVITE)
        print("You can use %s to invite as many number of people to the organization." % (invite_link,))
Ejemplo n.º 11
0
    def consume(self, data):
        # type: (Mapping[str, Any]) -> None
        invitee = get_prereg_user_by_email(data["email"])
        referrer = get_user_profile_by_id(data["referrer_id"])
        body = data["email_body"]
        do_send_confirmation_email(invitee, referrer, body)

        # queue invitation reminder for two days from now.
        link = create_confirmation_link(invitee, referrer.realm.host, Confirmation.INVITATION)
        context = common_context(referrer)
        context.update({
            'activate_url': link,
            'referrer_name': referrer.full_name,
            'referrer_email': referrer.email,
            'referrer_realm_name': referrer.realm.name,
        })
        send_future_email(
            "zerver/emails/invitation_reminder",
            to_email=data["email"],
            from_address=FromAddress.NOREPLY,
            context=context,
            delay=datetime.timedelta(days=2))
Ejemplo n.º 12
0
def send_registration_completion_email(email: str, request: HttpRequest,
                                       realm_creation: bool=False,
                                       streams: Optional[List[Stream]]=None) -> None:
    """
    Send an email with a confirmation link to the provided e-mail so the user
    can complete their registration.
    """
    prereg_user = create_preregistration_user(email, request, realm_creation)

    if streams is not None:
        prereg_user.streams = streams
        prereg_user.save()

    confirmation_type = Confirmation.USER_REGISTRATION
    if realm_creation:
        confirmation_type = Confirmation.REALM_CREATION

    activation_url = create_confirmation_link(prereg_user, request.get_host(), confirmation_type)
    send_email('zerver/emails/confirm_registration', to_email=email, from_address=FromAddress.NOREPLY,
               context={'activate_url': activation_url})
    if settings.DEVELOPMENT and realm_creation:
        request.session['confirmation_key'] = {'confirmation_key': activation_url.split('/')[-1]}
Ejemplo n.º 13
0
    def test_change_delivery_email_end_to_end_with_admins_visibility(
            self) -> None:
        user_profile = self.example_user("hamlet")
        do_set_realm_property(
            user_profile.realm,
            "email_address_visibility",
            Realm.EMAIL_ADDRESS_VISIBILITY_ADMINS,
            acting_user=None,
        )

        self.login_user(user_profile)
        old_email = user_profile.delivery_email
        new_email = "*****@*****.**"
        obj = EmailChangeStatus.objects.create(
            new_email=new_email,
            old_email=old_email,
            user_profile=user_profile,
            realm=user_profile.realm,
        )
        url = create_confirmation_link(obj, Confirmation.EMAIL_CHANGE)
        response = self.client_get(url)

        self.assertEqual(response.status_code, 200)
        self.assert_in_success_response(
            ["This confirms that the email address for your Zulip"], response)
        user_profile = get_user_profile_by_id(user_profile.id)
        self.assertEqual(user_profile.delivery_email, new_email)
        self.assertEqual(user_profile.email,
                         f"user{user_profile.id}@zulip.testserver")
        obj.refresh_from_db()
        self.assertEqual(obj.status, 1)
        with self.assertRaises(UserProfile.DoesNotExist):
            get_user(old_email, user_profile.realm)
        with self.assertRaises(UserProfile.DoesNotExist):
            get_user_by_delivery_email(old_email, user_profile.realm)
        self.assertEqual(
            get_user_by_delivery_email(new_email, user_profile.realm),
            user_profile)
Ejemplo n.º 14
0
    def handle(self, *args: Any, **options: Any) -> None:
        duplicates = False
        realm = self.get_realm(options)
        assert realm is not None  # Should be ensured by parser

        if not options['emails']:
            self.print_help("./manage.py", "generate_invite_links")
            raise CommandError

        for email in options['emails']:
            try:
                self.get_user(email, realm)
                print(
                    email +
                    ": There is already a user registered with that address.")
                duplicates = True
                continue
            except CommandError:
                pass

        if duplicates:
            return

        for email in options['emails']:
            try:
                email_allowed_for_realm(email, realm)
            except DomainNotAllowedForRealmError:
                if not options["force"]:
                    raise CommandError(
                        "You've asked to add an external user '{}' to a "
                        "closed realm '{}'.\nAre you sure? To do this, "
                        "pass --force.".format(email, realm.string_id))

            prereg_user = PreregistrationUser(email=email, realm=realm)
            prereg_user.save()
            print(
                email + ": " +
                create_confirmation_link(prereg_user, Confirmation.INVITATION))
Ejemplo n.º 15
0
    def consume(self, data):
        # type: (Mapping[str, Any]) -> None
        invitee = get_prereg_user_by_email(data["email"])
        referrer = get_user_profile_by_id(data["referrer_id"])
        body = data["email_body"]
        logging.info("Sending invitation for realm %s to %s" % (referrer.realm.string_id, invitee.email))
        do_send_confirmation_email(invitee, referrer, body)

        # queue invitation reminder for two days from now.
        link = create_confirmation_link(invitee, referrer.realm.host, Confirmation.INVITATION)
        context = common_context(referrer)
        context.update({
            'activate_url': link,
            'referrer_name': referrer.full_name,
            'referrer_email': referrer.email,
            'referrer_realm_name': referrer.realm.name,
        })
        send_future_email(
            "zerver/emails/invitation_reminder",
            to_email=data["email"],
            from_address=FromAddress.NOREPLY,
            context=context,
            delay=datetime.timedelta(days=2))
Ejemplo n.º 16
0
def do_send_realm_reactivation_email(
        realm: Realm, *, acting_user: Optional[UserProfile]) -> None:
    url = create_confirmation_link(realm, Confirmation.REALM_REACTIVATION)
    RealmAuditLog.objects.create(
        realm=realm,
        acting_user=acting_user,
        event_type=RealmAuditLog.REALM_REACTIVATION_EMAIL_SENT,
        event_time=timezone_now(),
    )
    context = {
        "confirmation_url": url,
        "realm_uri": realm.uri,
        "realm_name": realm.name
    }
    language = realm.default_language
    send_email_to_admins(
        "zerver/emails/realm_reactivation",
        realm,
        from_address=FromAddress.tokenized_no_reply_address(),
        from_name=FromAddress.security_email_from_name(language=language),
        language=language,
        context=context,
    )
Ejemplo n.º 17
0
    def handle(self, *args, **options):
        # type: (*Any, **Any) -> None
        duplicates = False
        realm = self.get_realm(options)
        assert realm is not None  # Should be ensured by parser

        if not options['emails']:
            self.print_help("./manage.py", "generate_invite_links")
            exit(1)

        for email in options['emails']:
            try:
                self.get_user(email, realm)
                print(
                    email +
                    ": There is already a user registered with that address.")
                duplicates = True
                continue
            except CommandError:
                pass

        if duplicates:
            return

        for email in options['emails']:
            if not email_allowed_for_realm(email,
                                           realm) and not options["force"]:
                print(
                    "You've asked to add an external user '%s' to a closed realm '%s'."
                    % (email, realm.string_id))
                print("Are you sure? To do this, pass --force.")
                exit(1)

            prereg_user = PreregistrationUser(email=email, realm=realm)
            prereg_user.save()
            print(email + ": " + create_confirmation_link(
                prereg_user, realm.host, Confirmation.INVITATION))
Ejemplo n.º 18
0
def prepare_activation_url(email: str,
                           request: HttpRequest,
                           realm_creation: bool = False,
                           streams: Optional[List[Stream]] = None) -> str:
    """
    Send an email with a confirmation link to the provided e-mail so the user
    can complete their registration.
    """
    prereg_user = create_preregistration_user(email, request, realm_creation)

    if streams is not None:
        prereg_user.streams.set(streams)

    confirmation_type = Confirmation.USER_REGISTRATION
    if realm_creation:
        confirmation_type = Confirmation.REALM_CREATION

    activation_url = create_confirmation_link(prereg_user, request.get_host(),
                                              confirmation_type)
    if settings.DEVELOPMENT and realm_creation:
        request.session['confirmation_key'] = {
            'confirmation_key': activation_url.split('/')[-1]
        }
    return activation_url
Ejemplo n.º 19
0
    def consume(self, data: Mapping[str, Any]) -> None:
        if "email" in data:
            # When upgrading from a version up through 1.7.1, there may be
            # existing items in the queue with `email` instead of `prereg_id`.
            invitee = PreregistrationUser.objects.filter(
                email__iexact=data["email"].strip()).latest("invited_at")
        else:
            invitee = PreregistrationUser.objects.filter(
                id=data["prereg_id"]).first()
            if invitee is None:
                # The invitation could have been revoked
                return

        referrer = get_user_profile_by_id(data["referrer_id"])
        logger.info("Sending invitation for realm %s to %s" %
                    (referrer.realm.string_id, invitee.email))
        do_send_confirmation_email(invitee, referrer)

        # queue invitation reminder for two days from now.
        link = create_confirmation_link(invitee, referrer.realm.host,
                                        Confirmation.INVITATION)
        context = common_context(referrer)
        context.update({
            'activate_url': link,
            'referrer_name': referrer.full_name,
            'referrer_email': referrer.email,
            'referrer_realm_name': referrer.realm.name,
        })
        send_future_email(
            "zerver/emails/invitation_reminder",
            referrer.realm,
            to_emails=[invitee.email],
            from_address=FromAddress.tokenized_no_reply_address(),
            language=referrer.realm.default_language,
            context=context,
            delay=datetime.timedelta(days=2))
Ejemplo n.º 20
0
def register_development_realm(request: HttpRequest) -> HttpResponse:
    count = UserProfile.objects.count()
    name = f"user-{count}"
    email = f"{name}@zulip.com"
    realm_name = f"realm-{count}"
    prereg = create_preregistration_user(email,
                                         request,
                                         realm_creation=True,
                                         password_required=False)
    activation_url = create_confirmation_link(prereg,
                                              Confirmation.REALM_CREATION)
    key = activation_url.split("/")[-1]
    # Need to add test data to POST request as it doesn't originally contain the required parameters
    modify_postdata(
        request,
        key=key,
        realm_name=realm_name,
        full_name=name,
        password="******",
        realm_subdomain=realm_name,
        terms="true",
    )

    return accounts_register(request)
Ejemplo n.º 21
0
def maybe_send_to_registration(request: HttpRequest,
                               email: str,
                               full_name: str = '',
                               is_signup: bool = False,
                               password_required: bool = True,
                               multiuse_object_key: str = '') -> HttpResponse:
    """Given a successful authentication for an email address (i.e. we've
    confirmed the user controls the email address) that does not
    currently have a Zulip account in the target realm, send them to
    the registration flow or the "continue to registration" flow,
    depending on is_signup, whether the email address can join the
    organization (checked in HomepageForm), and similar details.
    """
    realm = get_realm(get_subdomain(request))
    from_multiuse_invite = False
    multiuse_obj = None
    streams_to_subscribe = None
    invited_as = PreregistrationUser.INVITE_AS['MEMBER']
    if multiuse_object_key:
        from_multiuse_invite = True
        multiuse_obj = Confirmation.objects.get(
            confirmation_key=multiuse_object_key).content_object
        realm = multiuse_obj.realm
        streams_to_subscribe = multiuse_obj.streams.all()
        invited_as = multiuse_obj.invited_as

    form = HomepageForm({'email': email},
                        realm=realm,
                        from_multiuse_invite=from_multiuse_invite)
    if form.is_valid():
        # If the email address is allowed to sign up for an account in
        # this organization, construct a PreregistrationUser and
        # Confirmation objects, and then send the user to account
        # creation or confirm-continue-registration depending on
        # is_signup.
        prereg_user = None
        if settings.ONLY_SSO:
            try:
                prereg_user = PreregistrationUser.objects.filter(
                    email__iexact=email, realm=realm).latest("invited_at")
            except PreregistrationUser.DoesNotExist:
                prereg_user = create_preregistration_user(
                    email, request, password_required=password_required)
        else:
            prereg_user = create_preregistration_user(
                email, request, password_required=password_required)

        if multiuse_object_key:
            request.session.modified = True
            if streams_to_subscribe is not None:
                prereg_user.streams.set(streams_to_subscribe)
            prereg_user.invited_as = invited_as
            prereg_user.save()

        confirmation_link = create_confirmation_link(
            prereg_user, request.get_host(), Confirmation.USER_REGISTRATION)
        if is_signup:
            return redirect(confirmation_link)

        context = {
            'email': email,
            'continue_link': confirmation_link,
            'full_name': full_name
        }
        return render(request,
                      'zerver/confirm_continue_registration.html',
                      context=context)

    # This email address it not allowed to join this organization, so
    # just send the user back to the registration page.
    url = reverse('register')
    context = login_context(request)
    extra_context = {
        'form': form,
        'current_url': lambda: url,
        'from_multiuse_invite': from_multiuse_invite,
        'multiuse_object_key': multiuse_object_key
    }  # type: Mapping[str, Any]
    context.update(extra_context)
    return render(request, 'zerver/accounts_home.html', context=context)
Ejemplo n.º 22
0
Archivo: auth.py Proyecto: syedfa/zulip
def maybe_send_to_registration(request: HttpRequest,
                               email: str,
                               full_name: str = '',
                               is_signup: bool = False,
                               password_required: bool = True) -> HttpResponse:
    realm = get_realm(get_subdomain(request))
    from_multiuse_invite = False
    multiuse_obj = None
    streams_to_subscribe = None
    multiuse_object_key = request.session.get("multiuse_object_key", None)
    invited_as = PreregistrationUser.INVITE_AS['MEMBER']
    if multiuse_object_key is not None:
        from_multiuse_invite = True
        multiuse_obj = Confirmation.objects.get(
            confirmation_key=multiuse_object_key).content_object
        realm = multiuse_obj.realm
        streams_to_subscribe = multiuse_obj.streams.all()
        invited_as = multiuse_obj.invited_as

    form = HomepageForm({'email': email},
                        realm=realm,
                        from_multiuse_invite=from_multiuse_invite)
    if form.is_valid():
        # Construct a PreregistrationUser object and send the user over to
        # the confirmation view.
        prereg_user = None
        if settings.ONLY_SSO:
            try:
                prereg_user = PreregistrationUser.objects.filter(
                    email__iexact=email, realm=realm).latest("invited_at")
            except PreregistrationUser.DoesNotExist:
                prereg_user = create_preregistration_user(
                    email, request, password_required=password_required)
        else:
            prereg_user = create_preregistration_user(
                email, request, password_required=password_required)

        if multiuse_object_key is not None:
            del request.session["multiuse_object_key"]
            request.session.modified = True
            if streams_to_subscribe is not None:
                prereg_user.streams.set(streams_to_subscribe)
            prereg_user.invited_as = invited_as
            prereg_user.save()

        confirmation_link = create_confirmation_link(
            prereg_user, request.get_host(), Confirmation.USER_REGISTRATION)
        if is_signup:
            return redirect(confirmation_link)

        context = {
            'email': email,
            'continue_link': confirmation_link,
            'full_name': full_name
        }
        return render(request,
                      'zerver/confirm_continue_registration.html',
                      context=context)
    else:
        url = reverse('register')
        return render(
            request,
            'zerver/accounts_home.html',
            context={
                'form': form,
                'current_url': lambda: url,
                'from_multiuse_invite': from_multiuse_invite
            },
        )
Ejemplo n.º 23
0
Archivo: auth.py Proyecto: deltay/zulip
def maybe_send_to_registration(request: HttpRequest, email: str, full_name: str='',
                               is_signup: bool=False, password_required: bool=True,
                               multiuse_object_key: str='') -> HttpResponse:
    """Given a successful authentication for an email address (i.e. we've
    confirmed the user controls the email address) that does not
    currently have a Zulip account in the target realm, send them to
    the registration flow or the "continue to registration" flow,
    depending on is_signup, whether the email address can join the
    organization (checked in HomepageForm), and similar details.
    """
    realm = get_realm(get_subdomain(request))
    from_multiuse_invite = False
    multiuse_obj = None
    streams_to_subscribe = None
    invited_as = PreregistrationUser.INVITE_AS['MEMBER']
    if multiuse_object_key:
        from_multiuse_invite = True
        multiuse_obj = Confirmation.objects.get(confirmation_key=multiuse_object_key).content_object
        realm = multiuse_obj.realm
        streams_to_subscribe = multiuse_obj.streams.all()
        invited_as = multiuse_obj.invited_as

    form = HomepageForm({'email': email}, realm=realm, from_multiuse_invite=from_multiuse_invite)
    if form.is_valid():
        # If the email address is allowed to sign up for an account in
        # this organization, construct a PreregistrationUser and
        # Confirmation objects, and then send the user to account
        # creation or confirm-continue-registration depending on
        # is_signup.
        prereg_user = None
        if settings.ONLY_SSO:
            try:
                prereg_user = PreregistrationUser.objects.filter(
                    email__iexact=email, realm=realm).latest("invited_at")
            except PreregistrationUser.DoesNotExist:
                prereg_user = create_preregistration_user(email, request,
                                                          password_required=password_required)
        else:
            prereg_user = create_preregistration_user(email, request,
                                                      password_required=password_required)

        if multiuse_object_key:
            request.session.modified = True
            if streams_to_subscribe is not None:
                prereg_user.streams.set(streams_to_subscribe)
            prereg_user.invited_as = invited_as
            prereg_user.save()

        confirmation_link = create_confirmation_link(prereg_user, request.get_host(),
                                                     Confirmation.USER_REGISTRATION)
        if is_signup:
            return redirect(confirmation_link)

        context = {'email': email,
                   'continue_link': confirmation_link,
                   'full_name': full_name}
        return render(request,
                      'zerver/confirm_continue_registration.html',
                      context=context)

    # This email address it not allowed to join this organization, so
    # just send the user back to the registration page.
    url = reverse('register')
    return render(request,
                  'zerver/accounts_home.html',
                  context={'form': form, 'current_url': lambda: url,
                           'from_multiuse_invite': from_multiuse_invite,
                           'multiuse_object_key': multiuse_object_key})
Ejemplo n.º 24
0
def maybe_send_to_registration(request: HttpRequest,
                               email: str,
                               full_name: str = '',
                               is_signup: bool = False,
                               password_required: bool = True) -> HttpResponse:
    realm = get_realm(get_subdomain(request))
    from_multiuse_invite = False
    multiuse_obj = None
    streams_to_subscribe = None
    multiuse_object_key = request.session.get("multiuse_object_key", None)
    if multiuse_object_key is not None:
        from_multiuse_invite = True
        multiuse_obj = Confirmation.objects.get(
            confirmation_key=multiuse_object_key).content_object
        realm = multiuse_obj.realm
        streams_to_subscribe = multiuse_obj.streams.all()

    form = HomepageForm({'email': email},
                        realm=realm,
                        from_multiuse_invite=from_multiuse_invite)
    if form.is_valid():
        # Construct a PreregistrationUser object and send the user over to
        # the confirmation view.
        prereg_user = None
        if settings.ONLY_SSO:
            try:
                prereg_user = PreregistrationUser.objects.filter(
                    email__iexact=email, realm=realm).latest("invited_at")
            except PreregistrationUser.DoesNotExist:
                prereg_user = create_preregistration_user(
                    email, request, password_required=password_required)
        else:
            prereg_user = create_preregistration_user(
                email, request, password_required=password_required)

        if multiuse_object_key is not None:
            del request.session["multiuse_object_key"]
            request.session.modified = True
            if streams_to_subscribe is not None:
                prereg_user.streams.set(streams_to_subscribe)

        confirmation_link = "".join((
            create_confirmation_link(prereg_user, request.get_host(),
                                     Confirmation.USER_REGISTRATION),
            '?full_name=',
            # urllib does not handle Unicode, so coerece to encoded byte string
            # Explanation: http://stackoverflow.com/a/5605354/90777
            urllib.parse.quote_plus(full_name.encode('utf8'))))
        if is_signup:
            return redirect(confirmation_link)

        context = {'email': email, 'continue_link': confirmation_link}
        return render(request,
                      'zerver/confirm_continue_registration.html',
                      context=context)
    else:
        url = reverse('register')
        return render(
            request,
            'zerver/accounts_home.html',
            context={
                'form': form,
                'current_url': lambda: url,
                'from_multiuse_invite': from_multiuse_invite
            },
        )
Ejemplo n.º 25
0
def maybe_send_to_registration(request: HttpRequest,
                               email: Text,
                               full_name: Text = '',
                               is_signup: bool = False,
                               password_required: bool = True) -> HttpResponse:

    if not is_signup:
        # If the user isn't trying to sign up, we take them to a
        # special page asking them whether that's their intent; this
        # helps prevent accidental account creation when users pick
        # the wrong Google account.
        try:
            validate_email(email)
            invalid_email = False
        except ValidationError:
            # If email address is invalid, we can't send the user
            # PreregistrationUser flow.
            invalid_email = True
        context = {
            'full_name': full_name,
            'email': email,
            'invalid_email': invalid_email
        }
        return render(request,
                      'zerver/confirm_continue_registration.html',
                      context=context)

    realm = get_realm(get_subdomain(request))
    from_multiuse_invite = False
    multiuse_obj = None
    streams_to_subscribe = None
    multiuse_object_key = request.session.get("multiuse_object_key", None)
    if multiuse_object_key is not None:
        from_multiuse_invite = True
        multiuse_obj = Confirmation.objects.get(
            confirmation_key=multiuse_object_key).content_object
        realm = multiuse_obj.realm
        streams_to_subscribe = multiuse_obj.streams.all()

    form = HomepageForm({'email': email},
                        realm=realm,
                        from_multiuse_invite=from_multiuse_invite)
    if form.is_valid():
        # Construct a PreregistrationUser object and send the user over to
        # the confirmation view.
        prereg_user = None
        if settings.ONLY_SSO:
            try:
                prereg_user = PreregistrationUser.objects.filter(
                    email__iexact=email, realm=realm).latest("invited_at")
            except PreregistrationUser.DoesNotExist:
                prereg_user = create_preregistration_user(
                    email, request, password_required=password_required)
        else:
            prereg_user = create_preregistration_user(
                email, request, password_required=password_required)

        if multiuse_object_key is not None:
            del request.session["multiuse_object_key"]
            request.session.modified = True
            if streams_to_subscribe is not None:
                prereg_user.streams.set(streams_to_subscribe)

        confirmation_link = "".join((
            create_confirmation_link(prereg_user, request.get_host(),
                                     Confirmation.USER_REGISTRATION),
            '?full_name=',
            # urllib does not handle Unicode, so coerece to encoded byte string
            # Explanation: http://stackoverflow.com/a/5605354/90777
            urllib.parse.quote_plus(full_name.encode('utf8'))))
        return redirect(confirmation_link)
    else:
        url = reverse('register')
        return render(
            request,
            'zerver/accounts_home.html',
            context={
                'form': form,
                'current_url': lambda: url,
                'from_multiuse_invite': from_multiuse_invite
            },
        )
Ejemplo n.º 26
0
def maybe_send_to_registration(
        request: HttpRequest,
        email: str,
        full_name: str = '',
        is_signup: bool = False,
        password_required: bool = True,
        multiuse_object_key: str = '',
        full_name_validated: bool = False) -> HttpResponse:
    """Given a successful authentication for an email address (i.e. we've
    confirmed the user controls the email address) that does not
    currently have a Zulip account in the target realm, send them to
    the registration flow or the "continue to registration" flow,
    depending on is_signup, whether the email address can join the
    organization (checked in HomepageForm), and similar details.
    """
    if multiuse_object_key:
        from_multiuse_invite = True
        multiuse_obj = Confirmation.objects.get(
            confirmation_key=multiuse_object_key).content_object
        realm = multiuse_obj.realm
        invited_as = multiuse_obj.invited_as
    else:
        from_multiuse_invite = False
        multiuse_obj = None
        try:
            realm = get_realm(get_subdomain(request))
        except Realm.DoesNotExist:
            realm = None
        invited_as = PreregistrationUser.INVITE_AS['MEMBER']

    form = HomepageForm({'email': email},
                        realm=realm,
                        from_multiuse_invite=from_multiuse_invite)
    if form.is_valid():
        # If the email address is allowed to sign up for an account in
        # this organization, construct a PreregistrationUser and
        # Confirmation objects, and then send the user to account
        # creation or confirm-continue-registration depending on
        # is_signup.
        try:
            prereg_user = PreregistrationUser.objects.filter(
                email__iexact=email, realm=realm).latest("invited_at")

            # password_required and full_name data passed here as argument should take precedence
            # over the defaults with which the existing PreregistrationUser that we've just fetched
            # was created.
            prereg_user.password_required = password_required
            update_fields = ["password_required"]
            if full_name:
                prereg_user.full_name = full_name
                prereg_user.full_name_validated = full_name_validated
                update_fields.extend(["full_name", "full_name_validated"])
            prereg_user.save(update_fields=update_fields)
        except PreregistrationUser.DoesNotExist:
            prereg_user = create_preregistration_user(
                email,
                request,
                password_required=password_required,
                full_name=full_name,
                full_name_validated=full_name_validated)

        if multiuse_obj is not None:
            request.session.modified = True
            streams_to_subscribe = list(multiuse_obj.streams.all())
            prereg_user.streams.set(streams_to_subscribe)
            prereg_user.invited_as = invited_as
            prereg_user.save()

        # We want to create a confirmation link to create an account
        # in the current realm, i.e. one with a hostname of
        # realm.host.  For the Apache REMOTE_USER_SSO auth code path,
        # this is preferable over realm.get_host() because the latter
        # contains the port number of the Apache instance and we want
        # to send the user back to nginx.  But if we're in the realm
        # creation code path, there might not be a realm yet, so we
        # have to use request.get_host().
        if realm is not None:
            host = realm.host
        else:
            host = request.get_host()
        confirmation_link = create_confirmation_link(
            prereg_user, host, Confirmation.USER_REGISTRATION)
        if is_signup:
            return redirect(confirmation_link)

        context = {
            'email': email,
            'continue_link': confirmation_link,
            'full_name': full_name
        }
        return render(request,
                      'zerver/confirm_continue_registration.html',
                      context=context)

    # This email address it not allowed to join this organization, so
    # just send the user back to the registration page.
    url = reverse('register')
    context = login_context(request)
    extra_context = {
        'form': form,
        'current_url': lambda: url,
        'from_multiuse_invite': from_multiuse_invite,
        'multiuse_object_key': multiuse_object_key
    }  # type: Mapping[str, Any]
    context.update(extra_context)
    return render(request, 'zerver/accounts_home.html', context=context)
Ejemplo n.º 27
0
def maybe_send_to_registration(
    request: HttpRequest,
    email: str,
    full_name: str = "",
    mobile_flow_otp: Optional[str] = None,
    desktop_flow_otp: Optional[str] = None,
    is_signup: bool = False,
    password_required: bool = True,
    multiuse_object_key: str = "",
    full_name_validated: bool = False,
) -> HttpResponse:
    """Given a successful authentication for an email address (i.e. we've
    confirmed the user controls the email address) that does not
    currently have a Zulip account in the target realm, send them to
    the registration flow or the "continue to registration" flow,
    depending on is_signup, whether the email address can join the
    organization (checked in HomepageForm), and similar details.
    """

    # In the desktop and mobile registration flows, the sign up
    # happens in the browser so the user can use their
    # already-logged-in social accounts.  Then at the end, with the
    # user account created, we pass the appropriate data to the app
    # via e.g. a `zulip://` redirect.  We store the OTP keys for the
    # mobile/desktop flow in the session with 1-hour expiry, because
    # we want this configuration of having a successful authentication
    # result in being logged into the app to persist if the user makes
    # mistakes while trying to authenticate (E.g. clicks the wrong
    # Google account, hits back, etc.) during a given browser session,
    # rather than just logging into the webapp in the target browser.
    #
    # We can't use our usual pre-account-creation state storage
    # approach of putting something in PreregistrationUser, because
    # that would apply to future registration attempts on other
    # devices, e.g. just creating an account on the web on their laptop.
    assert not (mobile_flow_otp and desktop_flow_otp)
    if mobile_flow_otp:
        set_expirable_session_var(
            request.session, "registration_mobile_flow_otp", mobile_flow_otp, expiry_seconds=3600
        )
    elif desktop_flow_otp:
        set_expirable_session_var(
            request.session, "registration_desktop_flow_otp", desktop_flow_otp, expiry_seconds=3600
        )

    if multiuse_object_key:
        from_multiuse_invite = True
        multiuse_obj = Confirmation.objects.get(confirmation_key=multiuse_object_key).content_object
        realm = multiuse_obj.realm
        invited_as = multiuse_obj.invited_as
    else:
        from_multiuse_invite = False
        multiuse_obj = None
        try:
            realm = get_realm(get_subdomain(request))
        except Realm.DoesNotExist:
            realm = None
        invited_as = PreregistrationUser.INVITE_AS["MEMBER"]

    form = HomepageForm({"email": email}, realm=realm, from_multiuse_invite=from_multiuse_invite)
    if form.is_valid():
        # If the email address is allowed to sign up for an account in
        # this organization, construct a PreregistrationUser and
        # Confirmation objects, and then send the user to account
        # creation or confirm-continue-registration depending on
        # is_signup.
        try:
            prereg_user = filter_to_valid_prereg_users(
                PreregistrationUser.objects.filter(email__iexact=email, realm=realm)
            ).latest("invited_at")

            # password_required and full_name data passed here as argument should take precedence
            # over the defaults with which the existing PreregistrationUser that we've just fetched
            # was created.
            prereg_user.password_required = password_required
            update_fields = ["password_required"]
            if full_name:
                prereg_user.full_name = full_name
                prereg_user.full_name_validated = full_name_validated
                update_fields.extend(["full_name", "full_name_validated"])
            prereg_user.save(update_fields=update_fields)
        except PreregistrationUser.DoesNotExist:
            prereg_user = create_preregistration_user(
                email,
                request,
                password_required=password_required,
                full_name=full_name,
                full_name_validated=full_name_validated,
            )

        if multiuse_obj is not None:
            request.session.modified = True
            streams_to_subscribe = list(multiuse_obj.streams.all())
            prereg_user.streams.set(streams_to_subscribe)
            prereg_user.invited_as = invited_as
            prereg_user.save()

        confirmation_link = create_confirmation_link(prereg_user, Confirmation.USER_REGISTRATION)
        if is_signup:
            return redirect(confirmation_link)

        context = {"email": email, "continue_link": confirmation_link, "full_name": full_name}
        return render(request, "zerver/confirm_continue_registration.html", context=context)

    # This email address it not allowed to join this organization, so
    # just send the user back to the registration page.
    url = reverse("register")
    context = login_context(request)
    extra_context: Mapping[str, Any] = {
        "form": form,
        "current_url": lambda: url,
        "from_multiuse_invite": from_multiuse_invite,
        "multiuse_object_key": multiuse_object_key,
        "mobile_flow_otp": mobile_flow_otp,
        "desktop_flow_otp": desktop_flow_otp,
    }
    context.update(extra_context)
    return render(request, "zerver/accounts_home.html", context=context)
Ejemplo n.º 28
0
Archivo: auth.py Proyecto: qnxor/zulip
def maybe_send_to_registration(
        request: HttpRequest,
        email: str,
        full_name: str = '',
        mobile_flow_otp: Optional[str] = None,
        desktop_flow_otp: Optional[str] = None,
        is_signup: bool = False,
        password_required: bool = True,
        multiuse_object_key: str = '',
        full_name_validated: bool = False) -> HttpResponse:
    """Given a successful authentication for an email address (i.e. we've
    confirmed the user controls the email address) that does not
    currently have a Zulip account in the target realm, send them to
    the registration flow or the "continue to registration" flow,
    depending on is_signup, whether the email address can join the
    organization (checked in HomepageForm), and similar details.
    """

    # In the desktop and mobile registration flows, the sign up
    # happens in the browser so the user can use their
    # already-logged-in social accounts.  Then at the end, with the
    # user account created, we pass the appropriate data to the app
    # via e.g. a `zulip://` redirect.  We store the OTP keys for the
    # mobile/desktop flow in the session with 1-hour expiry, because
    # we want this configuration of having a successful authentication
    # result in being logged into the app to persist if the user makes
    # mistakes while trying to authenticate (E.g. clicks the wrong
    # Google account, hits back, etc.) during a given browser session,
    # rather than just logging into the webapp in the target browser.
    #
    # We can't use our usual pre-account-creation state storage
    # approach of putting something in PreregistrationUser, because
    # that would apply to future registration attempts on other
    # devices, e.g. just creating an account on the web on their laptop.
    assert not (mobile_flow_otp and desktop_flow_otp)
    if mobile_flow_otp:
        set_expirable_session_var(request.session,
                                  'registration_mobile_flow_otp',
                                  mobile_flow_otp,
                                  expiry_seconds=3600)
    elif desktop_flow_otp:
        set_expirable_session_var(request.session,
                                  'registration_desktop_flow_otp',
                                  desktop_flow_otp,
                                  expiry_seconds=3600)

    if multiuse_object_key:
        from_multiuse_invite = True
        multiuse_obj = Confirmation.objects.get(
            confirmation_key=multiuse_object_key).content_object
        realm = multiuse_obj.realm
        invited_as = multiuse_obj.invited_as
    else:
        from_multiuse_invite = False
        multiuse_obj = None
        try:
            realm = get_realm(get_subdomain(request))
        except Realm.DoesNotExist:
            realm = None
        invited_as = PreregistrationUser.INVITE_AS['MEMBER']

    form = HomepageForm({'email': email},
                        realm=realm,
                        from_multiuse_invite=from_multiuse_invite)
    if form.is_valid():
        # If the email address is allowed to sign up for an account in
        # this organization, construct a PreregistrationUser and
        # Confirmation objects, and then send the user to account
        # creation or confirm-continue-registration depending on
        # is_signup.
        try:
            prereg_user = PreregistrationUser.objects.filter(
                email__iexact=email, realm=realm).latest("invited_at")

            # password_required and full_name data passed here as argument should take precedence
            # over the defaults with which the existing PreregistrationUser that we've just fetched
            # was created.
            prereg_user.password_required = password_required
            update_fields = ["password_required"]
            if full_name:
                prereg_user.full_name = full_name
                prereg_user.full_name_validated = full_name_validated
                update_fields.extend(["full_name", "full_name_validated"])
            prereg_user.save(update_fields=update_fields)
        except PreregistrationUser.DoesNotExist:
            prereg_user = create_preregistration_user(
                email,
                request,
                password_required=password_required,
                full_name=full_name,
                full_name_validated=full_name_validated,
            )

        if multiuse_obj is not None:
            request.session.modified = True
            streams_to_subscribe = list(multiuse_obj.streams.all())
            prereg_user.streams.set(streams_to_subscribe)
            prereg_user.invited_as = invited_as
            prereg_user.save()

        # We want to create a confirmation link to create an account
        # in the current realm, i.e. one with a hostname of
        # realm.host.  For the Apache REMOTE_USER_SSO auth code path,
        # this is preferable over realm.get_host() because the latter
        # contains the port number of the Apache instance and we want
        # to send the user back to nginx.  But if we're in the realm
        # creation code path, there might not be a realm yet, so we
        # have to use request.get_host().
        if realm is not None:
            host = realm.host
        else:
            host = request.get_host()
        # Mark 'host' as safe for use in a redirect. It's pulled from the
        # current request or realm, both of which only allow a limited set of
        # trusted hosts.
        confirmation_link = create_confirmation_link(
            prereg_user, mark_sanitized(host), Confirmation.USER_REGISTRATION)
        if is_signup:
            return redirect(confirmation_link)

        context = {
            'email': email,
            'continue_link': confirmation_link,
            'full_name': full_name
        }
        return render(request,
                      'zerver/confirm_continue_registration.html',
                      context=context)

    # This email address it not allowed to join this organization, so
    # just send the user back to the registration page.
    url = reverse('register')
    context = login_context(request)
    extra_context: Mapping[str, Any] = {
        'form': form,
        'current_url': lambda: url,
        'from_multiuse_invite': from_multiuse_invite,
        'multiuse_object_key': multiuse_object_key,
        'mobile_flow_otp': mobile_flow_otp,
        'desktop_flow_otp': desktop_flow_otp,
    }
    context.update(extra_context)
    return render(request, 'zerver/accounts_home.html', context=context)