示例#1
0
def check_prereg_key_and_redirect(request: HttpRequest,
                                  confirmation_key: str) -> HttpResponse:
    confirmation = Confirmation.objects.filter(
        confirmation_key=confirmation_key).first()
    if confirmation is None or confirmation.type not in [
            Confirmation.USER_REGISTRATION,
            Confirmation.INVITATION,
            Confirmation.REALM_CREATION,
    ]:
        return render_confirmation_key_error(
            request,
            ConfirmationKeyException(ConfirmationKeyException.DOES_NOT_EXIST))

    prereg_user = confirmation.content_object
    if prereg_user.status == confirmation_settings.STATUS_REVOKED:
        return render(request, "zerver/confirmation_link_expired_error.html")

    try:
        get_object_from_key(confirmation_key,
                            confirmation.type,
                            activate_object=False)
    except ConfirmationKeyException as exception:
        return render_confirmation_key_error(request, exception)

    # confirm_preregistrationuser.html just extracts the confirmation_key
    # (and GET parameters) and redirects to /accounts/register, so that the
    # user can enter their information on a cleaner URL.
    return render(
        request,
        "confirmation/confirm_preregistrationuser.html",
        context={
            "key": confirmation_key,
            "full_name": request.GET.get("full_name", None)
        },
    )
示例#2
0
def check_prereg_key_and_redirect(request: HttpRequest,
                                  confirmation_key: str) -> HttpResponse:
    # If the key isn't valid, show the error message on the original URL
    confirmation = Confirmation.objects.filter(
        confirmation_key=confirmation_key).first()
    if confirmation is None or confirmation.type not in [
            Confirmation.USER_REGISTRATION, Confirmation.INVITATION,
            Confirmation.REALM_CREATION
    ]:
        return render_confirmation_key_error(
            request,
            ConfirmationKeyException(ConfirmationKeyException.DOES_NOT_EXIST))
    try:
        get_object_from_key(confirmation_key, confirmation.type)
    except ConfirmationKeyException as exception:
        return render_confirmation_key_error(request, exception)

    # confirm_preregistrationuser.html just extracts the confirmation_key
    # (and GET parameters) and redirects to /accounts/register, so that the
    # user can enter their information on a cleaner URL.
    return render(request,
                  'confirmation/confirm_preregistrationuser.html',
                  context={
                      'key': confirmation_key,
                      'full_name': request.GET.get("full_name", None)
                  })
示例#3
0
文件: views.py 项目: zjingjbj/zulip
def confirm(request, confirmation_key):
    # type: (HttpRequest, str) -> HttpResponse
    try:
        get_object_from_key(confirmation_key)
    except ConfirmationKeyException as exception:
        return render_confirmation_key_error(request, exception)

    return render(request, 'confirmation/confirm_preregistrationuser.html',
                  context={
                      'key': confirmation_key,
                      'full_name': request.GET.get("full_name", None)})
示例#4
0
def confirm(request: HttpRequest, confirmation_key: str) -> HttpResponse:
    try:
        get_object_from_key(confirmation_key, Confirmation.USER_REGISTRATION)
    except ConfirmationKeyException:
        try:
            get_object_from_key(confirmation_key, Confirmation.INVITATION)
        except ConfirmationKeyException as exception:
            return render_confirmation_key_error(request, exception)

    return render(request,
                  'confirmation/confirm_preregistrationuser.html',
                  context={
                      'key': confirmation_key,
                      'full_name': request.GET.get("full_name", None)
                  })
示例#5
0
def confirm_email_change(request, confirmation_key):
    # type: (HttpRequest, str) -> HttpResponse
    user_profile = request.user
    if user_profile.realm.email_changes_disabled:
        raise JsonableError(_("Email address changes are disabled in this organization."))

    confirmation_key = confirmation_key.lower()
    try:
        obj = get_object_from_key(confirmation_key)
    except ConfirmationKeyException as exception:
        return render_confirmation_key_error(request, exception)

    assert isinstance(obj, EmailChangeStatus)
    new_email = obj.new_email
    old_email = obj.old_email

    do_change_user_email(obj.user_profile, obj.new_email)

    context = {'realm': obj.realm, 'new_email': new_email}
    send_email('zerver/emails/notify_change_in_email', to_email=old_email,
               from_name="Zulip Account Security", from_address=FromAddress.SUPPORT,
               context=context)

    ctx = {
        'new_email': new_email,
        'old_email': old_email,
    }
    return render(request, 'confirmation/confirm_email_change.html', context=ctx)
示例#6
0
def confirm_email_change(request, confirmation_key):
    # type: (HttpRequest, str) -> HttpResponse
    user_profile = request.user
    if user_profile.realm.email_changes_disabled:
        raise JsonableError(_("Email address changes are disabled in this organization."))

    confirmation_key = confirmation_key.lower()
    try:
        obj = get_object_from_key(confirmation_key)
    except ConfirmationKeyException as exception:
        return render_confirmation_key_error(request, exception)

    assert isinstance(obj, EmailChangeStatus)
    new_email = obj.new_email
    old_email = obj.old_email

    do_change_user_email(obj.user_profile, obj.new_email)

    context = {'realm': obj.realm, 'new_email': new_email}
    send_email('zerver/emails/notify_change_in_email', to_email=old_email,
               from_name="Zulip Account Security", from_address=FromAddress.SUPPORT,
               context=context)

    ctx = {
        'new_email': new_email,
        'old_email': old_email,
    }
    return render(request, 'confirmation/confirm_email_change.html', context=ctx)
示例#7
0
def confirm_email_change(request: HttpRequest,
                         confirmation_key: str) -> HttpResponse:
    try:
        email_change_object = get_object_from_key(confirmation_key,
                                                  Confirmation.EMAIL_CHANGE)
    except ConfirmationKeyException as exception:
        return render_confirmation_key_error(request, exception)

    new_email = email_change_object.new_email
    old_email = email_change_object.old_email
    user_profile = email_change_object.user_profile

    if user_profile.realm.email_changes_disabled and not user_profile.is_realm_admin:
        raise JsonableError(
            _("Email address changes are disabled in this organization."))
    do_change_user_email(user_profile, new_email)

    context = {'realm': user_profile.realm, 'new_email': new_email}
    send_email('zerver/emails/notify_change_in_email',
               to_email=old_email,
               from_name="Zulip Account Security",
               from_address=FromAddress.SUPPORT,
               context=context)

    ctx = {
        'new_email': new_email,
        'old_email': old_email,
    }
    return render(request,
                  'confirmation/confirm_email_change.html',
                  context=ctx)
示例#8
0
def confirm_email_change(request: HttpRequest, confirmation_key: str) -> HttpResponse:
    try:
        email_change_object = get_object_from_key(confirmation_key, Confirmation.EMAIL_CHANGE)
    except ConfirmationKeyException as exception:
        return render_confirmation_key_error(request, exception)

    new_email = email_change_object.new_email
    old_email = email_change_object.old_email
    user_profile = email_change_object.user_profile

    if user_profile.realm.email_changes_disabled and not user_profile.is_realm_admin:
        raise JsonableError(_("Email address changes are disabled in this organization."))

    do_change_user_delivery_email(user_profile, new_email)

    context = {'realm_name': user_profile.realm.name, 'new_email': new_email}
    send_email('zerver/emails/notify_change_in_email', to_emails=[old_email],
               from_name="Zulip Account Security", from_address=FromAddress.SUPPORT,
               language=user_profile.default_language, context=context)

    ctx = {
        'new_email': new_email,
        'old_email': old_email,
    }
    return render(request, 'confirmation/confirm_email_change.html', context=ctx)
示例#9
0
def confirm_email_change(request: HttpRequest, confirmation_key: str) -> HttpResponse:
    try:
        email_change_object = get_object_from_key(confirmation_key, Confirmation.EMAIL_CHANGE)
    except ConfirmationKeyException as exception:
        return render_confirmation_key_error(request, exception)

    new_email = email_change_object.new_email
    old_email = email_change_object.old_email
    user_profile = email_change_object.user_profile

    if user_profile.realm.email_changes_disabled and not user_profile.is_realm_admin:
        raise JsonableError(_("Email address changes are disabled in this organization."))

    do_change_user_delivery_email(user_profile, new_email)

    context = {'realm_name': user_profile.realm.name, 'new_email': new_email}
    language = user_profile.default_language
    send_email('zerver/emails/notify_change_in_email', to_emails=[old_email],
               from_name=FromAddress.security_email_from_name(user_profile=user_profile),
               from_address=FromAddress.SUPPORT, language=language,
               context=context,
               realm=user_profile.realm)

    ctx = {
        'new_email_html_tag': SafeString(f'<a href="mailto:{escape(new_email)}">{escape(new_email)}</a>'),
        'old_email_html_tag': SafeString(f'<a href="mailto:{escape(old_email)}">{escape(old_email)}</a>'),

    }
    return render(request, 'confirmation/confirm_email_change.html', context=ctx)
示例#10
0
文件: realm.py 项目: rishig/zulip
def realm_reactivation(request: HttpRequest, confirmation_key: str) -> HttpResponse:
    try:
        realm = get_object_from_key(confirmation_key, Confirmation.REALM_REACTIVATION)
    except ConfirmationKeyException:
        return render(request, 'zerver/realm_reactivation_link_error.html')
    do_reactivate_realm(realm)
    context = {"realm": realm}
    return render(request, 'zerver/realm_reactivation.html', context)
示例#11
0
def realm_reactivation(request: HttpRequest, confirmation_key: str) -> HttpResponse:
    try:
        realm = get_object_from_key(confirmation_key, Confirmation.REALM_REACTIVATION)
    except ConfirmationKeyException:
        return render(request, 'zerver/realm_reactivation_link_error.html')
    do_reactivate_realm(realm)
    context = {"realm": realm}
    return render(request, 'zerver/realm_reactivation.html', context)
示例#12
0
def confirm(request, confirmation_key):
    # type: (HttpRequest, str) -> HttpResponse
    obj = get_object_from_key(confirmation_key)
    if obj:
        return render(request, 'confirmation/confirm_preregistrationuser.html',
                      context={
                          'key': confirmation_key,
                          'full_name': request.GET.get("full_name", None)})
    else:
        return render(request, 'confirmation/confirm.html', context = {'confirmed': False})
示例#13
0
def check_prereg_key_and_redirect(request: HttpRequest, confirmation_key: str) -> HttpResponse:
    # If the key isn't valid, show the error message on the original URL
    confirmation = Confirmation.objects.filter(confirmation_key=confirmation_key).first()
    if confirmation is None or confirmation.type not in [
            Confirmation.USER_REGISTRATION, Confirmation.INVITATION, Confirmation.REALM_CREATION]:
        return render_confirmation_key_error(
            request, ConfirmationKeyException(ConfirmationKeyException.DOES_NOT_EXIST))
    try:
        get_object_from_key(confirmation_key, confirmation.type)
    except ConfirmationKeyException as exception:
        return render_confirmation_key_error(request, exception)

    # confirm_preregistrationuser.html just extracts the confirmation_key
    # (and GET parameters) and redirects to /accounts/register, so that the
    # user can enter their information on a cleaner URL.
    return render(request, 'confirmation/confirm_preregistrationuser.html',
                  context={
                      'key': confirmation_key,
                      'full_name': request.GET.get("full_name", None)})
示例#14
0
def accounts_home_from_multiuse_invite(request, confirmation_key):
    # type: (HttpRequest, str) -> HttpResponse
    multiuse_object = None
    try:
        multiuse_object = get_object_from_key(confirmation_key)
    except ConfirmationKeyException as exception:
        realm = get_realm_from_request(request)
        if realm is None or realm.invite_required:
            return render_confirmation_key_error(request, exception)
    return accounts_home(request, multiuse_object=multiuse_object)
示例#15
0
def process_unsubscribe(request: HttpRequest, confirmation_key: str, subscription_type: str,
                        unsubscribe_function: Callable[[UserProfile], None]) -> HttpResponse:
    try:
        user_profile = get_object_from_key(confirmation_key, Confirmation.UNSUBSCRIBE)
    except ConfirmationKeyException:
        return render(request, 'zerver/unsubscribe_link_error.html')

    unsubscribe_function(user_profile)
    context = common_context(user_profile)
    context.update({"subscription_type": subscription_type})
    return render(request, 'zerver/unsubscribe_success.html', context=context)
示例#16
0
def process_unsubscribe(request: HttpRequest, confirmation_key: str, subscription_type: str,
                        unsubscribe_function: Callable[[UserProfile], None]) -> HttpResponse:
    try:
        user_profile = get_object_from_key(confirmation_key, Confirmation.UNSUBSCRIBE)
    except ConfirmationKeyException as exception:
        return render(request, 'zerver/unsubscribe_link_error.html')

    unsubscribe_function(user_profile)
    context = common_context(user_profile)
    context.update({"subscription_type": subscription_type})
    return render(request, 'zerver/unsubscribe_success.html', context=context)
示例#17
0
def accounts_home_from_multiuse_invite(request: HttpRequest, confirmation_key: str) -> HttpResponse:
    multiuse_object = None
    try:
        multiuse_object = get_object_from_key(confirmation_key, Confirmation.MULTIUSE_INVITE)
        # Required for oAuth2
        request.session["multiuse_object_key"] = confirmation_key
    except ConfirmationKeyException as exception:
        realm = get_realm_from_request(request)
        if realm is None or realm.invite_required:
            return render_confirmation_key_error(request, exception)
    return accounts_home(request, multiuse_object=multiuse_object)
示例#18
0
def accounts_home_from_multiuse_invite(request: HttpRequest, confirmation_key: str) -> HttpResponse:
    multiuse_object = None
    try:
        multiuse_object = get_object_from_key(confirmation_key, Confirmation.MULTIUSE_INVITE)
        # Required for oAuth2
        request.session["multiuse_object_key"] = confirmation_key
    except ConfirmationKeyException as exception:
        realm = get_realm_from_request(request)
        if realm is None or realm.invite_required:
            return render_confirmation_key_error(request, exception)
    return accounts_home(request, multiuse_object=multiuse_object)
示例#19
0
def realm_reactivation(request: HttpRequest,
                       confirmation_key: str) -> HttpResponse:
    try:
        realm = get_object_from_key(confirmation_key,
                                    [Confirmation.REALM_REACTIVATION])
    except ConfirmationKeyException:
        return render(request, "zerver/realm_reactivation_link_error.html")
    assert isinstance(realm, Realm)
    do_reactivate_realm(realm)
    context = {"realm": realm}
    return render(request, "zerver/realm_reactivation.html", context)
示例#20
0
def check_prereg_key(
        request: HttpRequest,
        confirmation_key: str) -> Union[Confirmation, HttpResponse]:
    """
    Checks if the Confirmation key is valid, returning the Confirmation object in case of success
    and an appropriate error page otherwise.
    """
    try:
        confirmation: Optional[Confirmation] = Confirmation.objects.get(
            confirmation_key=confirmation_key)
    except Confirmation.DoesNotExist:
        confirmation = None

    if confirmation is None or confirmation.type not in [
            Confirmation.USER_REGISTRATION,
            Confirmation.INVITATION,
            Confirmation.REALM_CREATION,
    ]:
        return render_confirmation_key_error(
            request,
            ConfirmationKeyException(ConfirmationKeyException.DOES_NOT_EXIST))

    prereg_user = confirmation.content_object
    assert prereg_user is not None
    if prereg_user.status == confirmation_settings.STATUS_REVOKED:
        return render(request,
                      "zerver/confirmation_link_expired_error.html",
                      status=404)

    try:
        get_object_from_key(confirmation_key,
                            confirmation.type,
                            activate_object=False)
    except ConfirmationKeyException as exception:
        return render_confirmation_key_error(request, exception)

    return confirmation
示例#21
0
def confirm_email_change(request: HttpRequest,
                         confirmation_key: str) -> HttpResponse:
    try:
        email_change_object = get_object_from_key(confirmation_key,
                                                  [Confirmation.EMAIL_CHANGE])
    except ConfirmationKeyException as exception:
        return render_confirmation_key_error(request, exception)

    new_email = email_change_object.new_email
    old_email = email_change_object.old_email
    user_profile = email_change_object.user_profile

    if user_profile.realm.deactivated:
        return redirect_to_deactivation_notice()

    if not user_profile.is_active:
        # TODO: Make this into a user-facing error, not JSON
        raise UserDeactivatedError()

    if user_profile.realm.email_changes_disabled and not user_profile.is_realm_admin:
        raise JsonableError(
            _("Email address changes are disabled in this organization."))

    do_change_user_delivery_email(user_profile, new_email)

    context = {"realm_name": user_profile.realm.name, "new_email": new_email}
    language = user_profile.default_language
    send_email(
        "zerver/emails/notify_change_in_email",
        to_emails=[old_email],
        from_name=FromAddress.security_email_from_name(
            user_profile=user_profile),
        from_address=FromAddress.SUPPORT,
        language=language,
        context=context,
        realm=user_profile.realm,
    )

    ctx = {
        "new_email_html_tag":
        SafeString(
            f'<a href="mailto:{escape(new_email)}">{escape(new_email)}</a>'),
        "old_email_html_tag":
        SafeString(
            f'<a href="mailto:{escape(old_email)}">{escape(old_email)}</a>'),
    }
    return render(request,
                  "confirmation/confirm_email_change.html",
                  context=ctx)
示例#22
0
def process_unsubscribe(
    request: HttpRequest,
    confirmation_key: str,
    subscription_type: str,
    unsubscribe_function: Callable[[UserProfile], None],
) -> HttpResponse:
    try:
        user_profile = get_object_from_key(confirmation_key, [Confirmation.UNSUBSCRIBE])
    except ConfirmationKeyException:
        return render(request, "zerver/unsubscribe_link_error.html")

    assert isinstance(user_profile, UserProfile)
    unsubscribe_function(user_profile)
    context = common_context(user_profile)
    context.update(subscription_type=subscription_type)
    return render(request, "zerver/unsubscribe_success.html", context=context)
示例#23
0
def accounts_home_from_multiuse_invite(request: HttpRequest, confirmation_key: str) -> HttpResponse:
    realm = get_realm_from_request(request)
    multiuse_object: Optional[MultiuseInvite] = None
    try:
        confirmation_obj = get_object_from_key(confirmation_key, [Confirmation.MULTIUSE_INVITE])
        assert isinstance(confirmation_obj, MultiuseInvite)
        multiuse_object = confirmation_obj
        if realm != multiuse_object.realm:
            return render(request, "confirmation/link_does_not_exist.html", status=404)
        # Required for OAuth 2
    except ConfirmationKeyException as exception:
        if realm is None or realm.invite_required:
            return render_confirmation_key_error(request, exception)
    return accounts_home(
        request, multiuse_object_key=confirmation_key, multiuse_object=multiuse_object
    )
示例#24
0
def check_prereg_key(request: HttpRequest, confirmation_key: str) -> PreregistrationUser:
    """
    Checks if the Confirmation key is valid, returning the PreregistrationUser object in case of success
    and raising an appropriate ConfirmationKeyException otherwise.
    """
    confirmation_types = [
        Confirmation.USER_REGISTRATION,
        Confirmation.INVITATION,
        Confirmation.REALM_CREATION,
    ]

    prereg_user = get_object_from_key(confirmation_key, confirmation_types, activate_object=False)

    if prereg_user.status == confirmation_settings.STATUS_REVOKED:
        raise ConfirmationKeyException(ConfirmationKeyException.EXPIRED)

    return prereg_user
示例#25
0
文件: auth.py 项目: gvarun1/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 web app 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)

    multiuse_obj: Optional[MultiuseInvite] = None
    from_multiuse_invite = False
    if multiuse_object_key:
        from_multiuse_invite = True
        try:
            multiuse_obj = get_object_from_key(multiuse_object_key,
                                               Confirmation.MULTIUSE_INVITE)
        except ConfirmationKeyException:
            return render(request,
                          "zerver/confirmation_link_expired_error.html",
                          status=404)

        realm = multiuse_obj.realm
        invited_as = multiuse_obj.invited_as
    else:
        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)