Exemple #1
0
def user_confirm_email(request):
    token = request.matchdict.get('ticket')
    email = verify_email_token(token)
    session = AbstractAgentAccount.default_db
    # TODO: token expiry
    localizer = request.localizer
    if not email:
        raise HTTPUnauthorized(localizer.translate(_("Wrong email token.")))
    assert isinstance(email.profile, User)
    user = email.profile
    username = user.username.username if user.username else None
    userid = user.id
    slug = request.matchdict.get('discussion_slug', None)
    if not slug:
        # We do not know from which discussion the user started to log in;
        # See if only involved in one discussion
        discussions = user.involved_in_discussion
        if len(discussions) == 1:
            slug = discussions[0].slug
    next_view = handle_next_view(request, False)

    if email.verified:
        return HTTPFound(location=maybe_contextual_route(
            request, 'login', _query=dict(message=localizer.translate(
                _("Email <%s> already confirmed")) % (email.email,))))
    else:
        # maybe another profile already verified that email
        other_email_account = session.query(AbstractAgentAccount).filter_by(
            email=email.email, verified=True).first()
        if other_email_account:
            profile = email.profile
            # We have two versions of the email, delete the unverified one
            session.delete(email)
            if other_email_account.profile != email.profile:
                # Give priority to the one where the email was verified last.
                other_profile = other_email_account.profile
                profile.merge(other_profile)
                session.delete(other_profile)
            email = other_email_account
        email.verified = True
        email.profile.verified = True
        user = None
        username = None
        userid = None
        if isinstance(email.profile, User):
            user = email.profile
            if user.username:
                username = user.username.username
            userid = user.id
        if user:
            # if option is active in discussion, auto-subscribe
            # user to discussion's default notifications
            discussion = None
            if slug:
                discussion = session.query(Discussion).filter_by(
                    slug=slug).first()
            if maybe_auto_subscribe(user, discussion):
                custom_message = localizer.translate(_(
                    "Your email address %s has been confirmed, "
                    "and you are now subscribed to discussion's "
                    "default notifications.")) % (email.email,)
            else:
                custom_message = localizer.translate(_(
                    "Your email address %s has been confirmed,"
                    " you can now log in.")) % (email.email,)
            return dict(
                get_default_context(request),
                button_url=maybe_contextual_route(request, 'login'),
                button_label=localizer.translate(_('Log in')),
                title=localizer.translate(_('Your account is now active!')),
                description=custom_message)
        else:
            # we confirmed a profile without a user? Now what?
            raise HTTPServerError()
Exemple #2
0
def user_confirm_email(request):
    token = request.matchdict.get('ticket')
    email = verify_email_token(token)
    session = AbstractAgentAccount.default_db
    # TODO: token expiry
    localizer = request.localizer
    if not email:
        raise HTTPUnauthorized(localizer.translate(_("Wrong email token.")))
    assert isinstance(email.profile, User)
    user = email.profile
    username = user.username.username if user.username else None
    userid = user.id
    slug = request.matchdict.get('discussion_slug', None)
    if not slug:
        # We do not know from which discussion the user started to log in;
        # See if only involved in one discussion
        discussions = user.involved_in_discussion
        if len(discussions) == 1:
            slug = discussions[0].slug
    next_view = handle_next_view(request, False)

    if email.verified:
        return HTTPFound(location=maybe_contextual_route(
            request,
            'login',
            _query=dict(message=localizer.translate(
                _("Email <%s> already confirmed")) % (email.email, ))))
    else:
        # maybe another profile already verified that email
        other_email_account = session.query(AbstractAgentAccount).filter_by(
            email=email.email, verified=True).first()
        if other_email_account:
            profile = email.profile
            # We have two versions of the email, delete the unverified one
            session.delete(email)
            if other_email_account.profile != email.profile:
                # Give priority to the one where the email was verified last.
                other_profile = other_email_account.profile
                profile.merge(other_profile)
                session.delete(other_profile)
            email = other_email_account
        email.verified = True
        email.profile.verified = True
        user = None
        username = None
        userid = None
        if isinstance(email.profile, User):
            user = email.profile
            if user.username:
                username = user.username.username
            userid = user.id
        if user:
            # if option is active in discussion, auto-subscribe
            # user to discussion's default notifications
            discussion = None
            if slug:
                discussion = session.query(Discussion).filter_by(
                    slug=slug).first()
            if maybe_auto_subscribe(user, discussion):
                custom_message = localizer.translate(
                    _("Your email address %s has been confirmed, "
                      "and you are now subscribed to discussion's "
                      "default notifications.")) % (email.email, )
            else:
                custom_message = localizer.translate(
                    _("Your email address %s has been confirmed,"
                      " you can now log in.")) % (email.email, )
            return dict(get_default_context(request),
                        button_url=maybe_contextual_route(request, 'login'),
                        button_label=localizer.translate(_('Log in')),
                        title=localizer.translate(
                            _('Your account is now active!')),
                        description=custom_message)
        else:
            # we confirmed a profile without a user? Now what?
            raise HTTPServerError()
Exemple #3
0
def user_confirm_email(request):
    token = request.matchdict.get('token') or ''
    account, validity = verify_email_token(token)
    session = AbstractAgentAccount.default_db
    logged_in = authenticated_userid(request)  # if mismatch?
    localizer = request.localizer
    if account and account.profile_id != logged_in:
        # token for someone else: forget login.
        logged_in = None
        forget(request)
    token_date = get_data_token_time(token)
    old_token = (
        account is None or token_date is None or (
            account.profile.last_login and token_date < account.profile.last_login))
    inferred_discussion = discussion = discussion_from_request(request)
    if account and not discussion:
        # We do not know from which discussion the user started to log in;
        # See if only involved in one discussion
        discussions = account.profile.involved_in_discussion
        if len(discussions) == 1:
            inferred_discussion = discussions[0]
    if account and account.verified and logged_in:
        # no need to revalidate, just send to discussion.
        # Question: maybe_auto_subscribe? Doubt it.
        if inferred_discussion:
            if inferred_discussion.preferences['landing_page']:
                route = 'new_home'
            else:
                route = 'home'
        else:
            route = 'discussion_list'
        error = localizer.translate(
            _("Email <%s> already confirmed")) % (account.email,)
        request.session.flash(error)
        return HTTPFound(location=request.route_url(
            route,
            discussion_slug=inferred_discussion.slug if inferred_discussion else None))

    if validity != Validity.VALID or old_token:
        # V-, B-: Invalid or obsolete token
        # Offer to send a new token
        if account and not account.verified:
            # bad token, unverified account... offer a new token
            if validity != Validity.VALID:
                error = localizer.translate(_(
                    "This link was not valid. We sent another."))
            else:
                error = localizer.translate(_(
                    "This link has been used. We sent another."))
            request.session.flash(error)
            return HTTPFound(location=maybe_contextual_route(
                request, 'confirm_emailid_sent', email_account_id=account.id))
        else:
            if account and account.verified:
                # bad token, verified account... send them to login
                error = localizer.translate(
                    _("Email <%s> already confirmed")) % (account.email,)
            else:
                # now what? We do not have the email.
                # Just send to login for now
                error = localizer.translate(_(
                    "This link is not valid. Please attempt to login to get another one."))
            request.session.flash(error)
            return HTTPFound(location=maybe_contextual_route(
                request, 'react_login', _query=dict(
                    identifier=account.email if account else None)))

    # By now we know we have a good token; make it login-equivalent.
    user = account.profile
    assert isinstance(user, User)  # accounts should not get here. OK to fail.
    headers = remember(request, user.id)
    request.response.headerlist.extend(headers)
    user.last_login = datetime.utcnow()
    username = user.username.username if user.username else None
    next_view = handle_next_view(request, False)

    if account.verified:
        message = localizer.translate(
            _("Email <%s> already confirmed")) % (account.email,)
    else:
        # maybe another profile already verified that email
        other_account = session.query(AbstractAgentAccount).filter_by(
            email_ci=account.email_ci, verified=True).first()
        if other_account:
            # We have two versions of the email, delete the unverified one
            session.delete(account)
            if other_account.profile != user:
                # Give priority to the one where the email was verified last.
                other_profile = other_account.profile
                user.merge(other_profile)
                session.delete(other_profile)
                if user.username:
                    username = user.username.username
            account = other_account
        account.verified = True
        user.verified = True
        # do not use inferred discussion for auto_subscribe
        user.last_login = datetime.utcnow()
        if discussion and maybe_auto_subscribe(user, discussion):
            message = localizer.translate(_(
                "Your email address %s has been confirmed, "
                "and you are now subscribed to discussion's "
                "default notifications.")) % (account.email,)
        else:
            message = localizer.translate(_(
                "Your email address %s has been confirmed."
                )) % (account.email,)

    if inferred_discussion:
        if inferred_discussion.preferences['landing_page']:
            route = 'new_home'
        else:
            route = 'home'
    else:
        route = 'discussion_list'
    return HTTPFound(location=request.route_url(
        route,
        discussion_slug=inferred_discussion.slug
        if inferred_discussion else None,
        _query=dict(message=message)))
Exemple #4
0
def user_confirm_email(request):
    token = request.matchdict.get('ticket')
    account, validity = verify_email_token(token)
    session = AbstractAgentAccount.default_db
    logged_in = authenticated_userid(request)  # if mismatch?
    localizer = request.localizer
    if account and account.profile_id != logged_in:
        # token for someone else: forget login.
        logged_in = None
        forget(request)
    token_date = get_data_token_time(token)
    old_token = (
        account is None or token_date is None or (
            account.profile.last_login and token_date < account.profile.last_login))
    inferred_discussion = discussion = discussion_from_request(request)
    if account and not discussion:
        # We do not know from which discussion the user started to log in;
        # See if only involved in one discussion
        discussions = account.profile.involved_in_discussion
        if len(discussions) == 1:
            inferred_discussion = discussions[0]
    if account.verified and logged_in:
        # no need to revalidate, just send to discussion.
        # Question: maybe_auto_subscribe? Doubt it.
        return HTTPFound(location=request.route_url(
            'home' if inferred_discussion else 'discussion_list',
            discussion_slug=inferred_discussion.slug,
            _query=dict(message=localizer.translate(
                _("Email <%s> already confirmed")) % (account.email,))))

    if validity != Validity.VALID or old_token:
        # V-, B-: Invalid or obsolete token
        # Offer to send a new token
        if account and not account.verified:
            # bad token, unverified account... offer a new token
            if validity != Validity.VALID:
                error = localizer.translate(_(
                    "This link was not valid. We sent another."))
            else:
                error = localizer.translate(_(
                    "This link has been used. We sent another."))
            return HTTPFound(location=maybe_contextual_route(
                request, 'confirm_emailid_sent', email_account_id=account.id,
                _query=(dict(error=error))))
        else:
            if account and account.verified:
                # bad token, verified account... send them to login
                error = localizer.translate(
                    _("Email <%s> already confirmed")) % (account.email,)
            else:
                # now what? We do not have the email.
                # Just send to login for now
                error = localizer.translate(_(
                    "This link is not valid. Please attempt to login to get another one."
                    )) % (account.email,)
            return HTTPFound(location=maybe_contextual_route(
                request, 'login', _query=dict(
                    identifier=account.email if account else None,
                    message=error)))

    # By now we know we have a good token; make it login-equivalent.
    user = account.profile
    assert isinstance(user, User)  # accounts should not get here. OK to fail.
    headers = remember(request, user.id)
    request.response.headerlist.extend(headers)
    user.last_login = datetime.utcnow()
    username = user.username.username if user.username else None
    next_view = handle_next_view(request, False)

    if account.verified:
        message = localizer.translate(
            _("Email <%s> already confirmed")) % (account.email,)
    else:
        # maybe another profile already verified that email
        other_account = session.query(AbstractAgentAccount).filter_by(
            email_ci=account.email_ci, verified=True).first()
        if other_account:
            # We have two versions of the email, delete the unverified one
            session.delete(account)
            if other_account.profile != user:
                # Give priority to the one where the email was verified last.
                other_profile = other_account.profile
                user.merge(other_profile)
                session.delete(other_profile)
                if user.username:
                    username = user.username.username
            account = other_account
        account.verified = True
        user.verified = True
        # do not use inferred discussion for auto_subscribe
        user.last_login = datetime.utcnow()
        if discussion and maybe_auto_subscribe(user, discussion):
            message = localizer.translate(_(
                "Your email address %s has been confirmed, "
                "and you are now subscribed to discussion's "
                "default notifications.")) % (account.email,)
        else:
            message = localizer.translate(_(
                "Your email address %s has been confirmed."
                )) % (account.email,)

    if inferred_discussion:
        return HTTPFound(location=request.route_url(
            'home', discussion_slug=inferred_discussion.slug,
            _query=dict(message=message)))
    else:
        return HTTPFound(
            location=request.route_url('discussion_list'))