Example #1
0
def handle_login(
    controller, form, responder, user, rem=None, signature=None, **kwargs
):
    # check captcha before login (if any) since its answer might
    # change once c.user is set.
    captcha_shown = not signature and need_provider_captcha("login")

    def _event(error, captcha_shown=captcha_shown):
        g.events.login_event(
            'login_attempt',
            error_msg=error,
            user_name=request.urlvars.get('url_user'),
            remember_me=rem,
            signature=signature,
            captcha_shown=captcha_shown,
            request=request,
            context=c)

    if signature and not signature.is_valid():
        _event(error="SIGNATURE")
        abort(403)

    hook_error = hooks.get_hook("account.login").call_until_return(
        responder=responder,
        request=request,
        context=c,
    )
    # if any of the hooks returned an error, abort the login.  The
    # set_error in this case also needs to exist in the hook.
    if hook_error:
        _event(error=hook_error)
        return

    exempt_ua = (request.user_agent and
                 any(ua in request.user_agent for ua
                     in g.config.get('exempt_login_user_agents', ())))
    if (errors.LOGGED_IN, None) in c.errors:
        if user == c.user or exempt_ua:
            # Allow funky clients to re-login as the current user.
            c.errors.remove((errors.LOGGED_IN, None))
        else:
            _event(error='LOGGED_IN')
            abort(reddit_http_error(409, errors.LOGGED_IN))

    if responder.has_errors("ratelimit", errors.RATELIMIT):
        _event(error='RATELIMIT')

    elif responder.has_errors("passwd", errors.WRONG_PASSWORD):
        _event(error='WRONG_PASSWORD')

    # last but not least, we have to check the captcha
    elif (not signature and not g.disable_captcha and
          not valid_provider_captcha(responder, "login")):
        _event(error='BAD_CAPTCHA')

    else:
        controller._login(responder, user, rem)
        _event(error=None)
Example #2
0
def handle_register(
    controller, form, responder, name, email,
    password, rem=None, newsletter_subscribe=False,
    sponsor=False, signature=None, **kwargs
):
    # check captcha before register (if any) since its answer might
    # change once c.user is set.
    captcha_shown = not signature and need_provider_captcha("register")

    def _event(error, captcha_shown=captcha_shown):
        g.events.login_event(
            'register_attempt',
            error_msg=error,
            user_name=request.urlvars.get('url_user'),
            email=request.POST.get('email'),
            remember_me=rem,
            newsletter=newsletter_subscribe,
            captcha_shown=captcha_shown,
            signature=signature,
            request=request,
            context=c)

    if signature and not signature.is_valid():
        _event(error="SIGNATURE")
        abort(403)

    if responder.has_errors('user', errors.USERNAME_TOO_SHORT):
        _event(error='USERNAME_TOO_SHORT')

    elif responder.has_errors('user', errors.USERNAME_INVALID_CHARACTERS):
        _event(error='USERNAME_INVALID_CHARACTERS')

    elif responder.has_errors('user', errors.USERNAME_TAKEN_DEL):
        _event(error='USERNAME_TAKEN_DEL')

    elif responder.has_errors('user', errors.USERNAME_TAKEN):
        _event(error='USERNAME_TAKEN')

    elif responder.has_errors('email', errors.BAD_EMAIL):
        _event(error='BAD_EMAIL')

    elif responder.has_errors('passwd', errors.SHORT_PASSWORD):
        _event(error='SHORT_PASSWORD')

    elif responder.has_errors('passwd', errors.BAD_PASSWORD):
        # BAD_PASSWORD is set when SHORT_PASSWORD is set
        _event(error='BAD_PASSWORD')

    elif responder.has_errors('passwd2', errors.BAD_PASSWORD_MATCH):
        _event(error='BAD_PASSWORD_MATCH')

    elif responder.has_errors('ratelimit', errors.RATELIMIT):
        _event(error='RATELIMIT')

    elif newsletter_subscribe and not email:
        c.errors.add(errors.NEWSLETTER_NO_EMAIL, field="email")
        form.has_errors("email", errors.NEWSLETTER_NO_EMAIL)
        _event(error='NEWSLETTER_NO_EMAIL')

    elif sponsor and not email:
        c.errors.add(errors.SPONSOR_NO_EMAIL, field="email")
        form.has_errors("email", errors.SPONSOR_NO_EMAIL)
        _event(error='SPONSOR_NO_EMAIL')

    # last but not least, we have to check the captcha
    elif (not signature and not g.disable_captcha and
          not valid_provider_captcha(responder, "register")):
        _event(error='BAD_CAPTCHA')

    else:
        try:
            user = register(name, password, request.ip)
        except AccountExists:
            c.errors.add(errors.USERNAME_TAKEN, field="user")
            form.has_errors("user", errors.USERNAME_TAKEN)
            _event(error='USERNAME_TAKEN')
            return

        VRatelimit.ratelimit(rate_ip=True, prefix="rate_register_")

        # anything else we know (email, languages)?
        if email:
            user.set_email(email)
            emailer.verify_email(user)

        user.pref_lang = c.lang

        if (is_api("html") and
                feature.is_enabled("new_user_onboarding", user=user)):
            user.has_been_onboarded = False

        user._commit()

        amqp.add_item('new_account', user._fullname)

        hooks.get_hook("account.registered").call(user=user)

        reject = hooks.get_hook("account.spotcheck").call(account=user)
        if any(reject):
            _event(error='ACCOUNT_SPOTCHECK')
            return

        if newsletter_subscribe and email:
            try:
                newsletter.add_subscriber(email, source="register")
            except newsletter.NewsletterError as e:
                g.log.warning("Failed to subscribe: %r" % e)

        controller._login(responder, user, rem)
        _event(error=None)