Esempio n. 1
0
def password_reset_confirm(request, uidb64=None, token=None):
    """
    Pulled from django contrib so that we can add user into the form
    so then we can show relevant messages about the user.
    """
    assert uidb64 is not None and token is not None
    user = None
    try:
        uid_int = urlsafe_base64_decode(uidb64)
        user = UserProfile.objects.get(id=uid_int)
    except (ValueError, UserProfile.DoesNotExist, TypeError):
        pass

    if user is not None and default_token_generator.check_token(user, token):
        validlink = True
        if request.method == 'POST':
            form = forms.SetPasswordForm(user, request.POST)
            if form.is_valid():
                form.save()
                log_cef('Password Changed', 5, request,
                        username=user.username,
                        signature='PASSWORDCHANGED',
                        msg='User changed password')
                return redirect(reverse('django.contrib.auth.'
                                        'views.password_reset_complete'))
        else:
            form = forms.SetPasswordForm(user)
    else:
        validlink = False
        form = None

    return render(request, 'users/pwreset_confirm.html',
                  {'form': form, 'validlink': validlink})
Esempio n. 2
0
def password_reset_confirm(request, uidb64=None, token=None):
    """
    Pulled from django contrib so that we can add user into the form
    so then we can show relevant messages about the user.
    """
    assert uidb64 is not None and token is not None
    user = None
    try:
        uid_int = urlsafe_base64_decode(uidb64)
        user = UserProfile.objects.get(id=uid_int)
    except (ValueError, UserProfile.DoesNotExist):
        pass

    if user is not None and default_token_generator.check_token(user, token):
        validlink = True
        if request.method == "POST":
            form = forms.SetPasswordForm(user, request.POST)
            if form.is_valid():
                form.save()
                log_cef(
                    "Password Changed",
                    5,
                    request,
                    username=user.username,
                    signature="PASSWORDCHANGED",
                    msg="User changed password",
                )
                return redirect(reverse("django.contrib.auth." "views.password_reset_complete"))
        else:
            form = forms.SetPasswordForm(user)
    else:
        validlink = False
        form = None

    return render(request, "users/pwreset_confirm.html", {"form": form, "validlink": validlink})
Esempio n. 3
0
 def save(self, **kw):
     if not self.users_cache:
         log.info("Unknown email used for password reset: {email}".format(
             **self.cleaned_data))
         return
     for user in self.users_cache:
         log.info(u'Password reset email sent for user (%s)' % user)
         if user.needs_tougher_password:
             log_cef('Password Reset',
                     5,
                     self.request,
                     username=user,
                     signature='PASSWORDRESET',
                     msg='Privileged user requested password reset')
         else:
             log_cef('Password Reset',
                     5,
                     self.request,
                     username=user,
                     signature='PASSWORDRESET',
                     msg='User requested password reset')
     try:
         # Django calls send_mail() directly and has no option to pass
         # in fail_silently, so we have to catch the SMTP error ourselves
         self.base_save(**kw)
     except SMTPException, e:
         log.error("Failed to send mail for (%s): %s" % (user, e))
Esempio n. 4
0
def browserid_authenticate(request, assertion):
    """
    Verify a BrowserID login attempt. If the BrowserID assertion is
    good, but no account exists on AMO, create one.

    Request is only needed for logging. :(
    """
    backend = BrowserIDBackend()
    result = backend.verify(assertion, settings.SITE_URL)
    if not result:
        return (None, "BrowserID authentication failure.")
    email = result['email']
    users = UserProfile.objects.filter(email=email)
    if len(users) == 1:
        users[0].user.backend = 'django_browserid.auth.BrowserIDBackend'
        return (users[0], None)
    username = autocreate_username(email.partition('@')[0])
    if (settings.REGISTER_USER_LIMIT and
        UserProfile.objects.count() > settings.REGISTER_USER_LIMIT
        and not can_override_reg_limit(request)):
        _m = ('Sorry, no more registrations are allowed. '
              '<a href="https://developer.mozilla.org/en-US/apps">'
              'Learn more</a>')
        return (None, _m)
    profile = UserProfile.objects.create(username=username, email=email)
    profile.create_django_user()
    profile.user.backend = 'django_browserid.auth.BrowserIDBackend'
    if settings.APP_PREVIEW:
        profile.notes = '__market__'
    profile.user.save()
    profile.save()
    log_cef('New Account', 5, request, username=username,
            signature='AUTHNOTICE',
            msg='User created a new account (from BrowserID)')
    return (profile, None)
Esempio n. 5
0
def browserid_authenticate(request, assertion):
    """
    Verify a BrowserID login attempt. If the BrowserID assertion is
    good, but no account exists on AMO, create one.

    Request is only needed for logging. :(
    """
    backend = BrowserIDBackend()
    result = backend.verify(assertion, settings.SITE_URL)
    if not result:
        return (None, "BrowserID authentication failure.")
    email = result['email']
    users = UserProfile.objects.filter(email=email)
    if len(users) == 1:
        users[0].user.backend = 'django_browserid.auth.BrowserIDBackend'
        return (users[0], None)
    username = autocreate_username(email.partition('@')[0])
    source = (amo.LOGIN_SOURCE_MMO_BROWSERID if settings.MARKETPLACE else
              amo.LOGIN_SOURCE_AMO_BROWSERID)
    profile = UserProfile.objects.create(username=username, email=email,
                                         source=source, display_name=username)

    profile.create_django_user()
    profile.user.backend = 'django_browserid.auth.BrowserIDBackend'
    profile.user.save()
    profile.save()
    log_cef('New Account', 5, request, username=username,
            signature='AUTHNOTICE',
            msg='User created a new account (from BrowserID)')
    return (profile, None)
Esempio n. 6
0
def register(request):

    if settings.APP_PREVIEW:
        messages.error(request,
                       loc('Registrations must be through browserid.'))
        form = None

    elif (settings.REGISTER_USER_LIMIT and
          UserProfile.objects.count() > settings.REGISTER_USER_LIMIT
          and not can_override_reg_limit(request)):
        _m = loc('Sorry, no more registrations are allowed. '
                 '<a href="https://developer.mozilla.org/en-US/apps">'
                 'Learn more</a>')
        messages.error(request, _m, title_safe=True, message_safe=True)
        form = None

    elif request.user.is_authenticated():
        messages.info(request, _('You are already logged in to an account.'))
        form = None

    elif request.method == 'POST':

        form = forms.UserRegisterForm(request.POST)

        if form.is_valid():
            try:
                u = form.save(commit=False)
                u.set_password(form.cleaned_data['password'])
                u.generate_confirmationcode()
                u.save()
                u.create_django_user()
                log.info(u'Registered new account for user (%s)', u)
                log_cef('New Account', 5, request, username=u.username,
                        signature='AUTHNOTICE',
                        msg='User created a new account')

                u.email_confirmation_code()

                msg = _('Congratulations! Your user account was successfully '
                        'created.')
                messages.success(request, msg)

                msg = _(u'An email has been sent to your address {0} to '
                         'confirm your account. Before you can log in, you '
                         'have to activate your account by clicking on the '
                         'link provided in this email.').format(u.email)
                messages.info(request, _('Confirmation Email Sent'), msg)
            except IntegrityError, e:
                # I was unable to reproduce this, but I suspect it happens
                # when they POST twice quickly and the slaves don't have the
                # new info yet (total guess).  Anyway, I'm assuming the
                # first one worked properly, so this is still a success
                # case to tne end user so we just log it...
                log.error('Failed to register new user (%s): %s' % (u, e))

            return http.HttpResponseRedirect(reverse('users.login'))

        else:
            messages.error(request, _('There are errors in this form'),
                            _('Please correct them and resubmit.'))
Esempio n. 7
0
 def save(self, **kw):
     for user in self.users_cache:
         log.info(u"Password reset email sent for user (%s)" % user)
         if user.needs_tougher_password:
             log_cef(
                 "Password Reset",
                 5,
                 self.request,
                 username=user,
                 signature="PASSWORDRESET",
                 msg="Privileged user requested password reset",
             )
         else:
             log_cef(
                 "Password Reset",
                 5,
                 self.request,
                 username=user,
                 signature="PASSWORDRESET",
                 msg="User requested password reset",
             )
     try:
         # Django calls send_mail() directly and has no option to pass
         # in fail_silently, so we have to catch the SMTP error ourselves
         super(PasswordResetForm, self).save(**kw)
     except SMTPException, e:
         log.error("Failed to send mail for (%s): %s" % (user, e))
Esempio n. 8
0
def password_reset_confirm(request, uidb36=None, token=None):
    """
    Pulled from django contrib so that we can add user into the form
    so then we can show relevant messages about the user.
    """
    assert uidb36 is not None and token is not None
    user = None
    try:
        uid_int = base36_to_int(uidb36)
        user = UserProfile.objects.get(id=uid_int)
    except (ValueError, UserProfile.DoesNotExist):
        pass

    if user is not None and default_token_generator.check_token(user, token):
        validlink = True
        if request.method == 'POST':
            form = forms.SetPasswordForm(user, request.POST)
            if form.is_valid():
                form.save()
                log_cef('Password Changed', 5, request,
                        username=user.username,
                        signature='PASSWORDCHANGED',
                        msg='User changed password')
                return redirect(reverse('django.contrib.auth.'
                                        'views.password_reset_complete'))
        else:
            form = forms.SetPasswordForm(user)
    else:
        validlink = False
        form = None

    return jingo.render(request, 'users/pwreset_confirm.html',
                        {'form': form, 'validlink': validlink})
Esempio n. 9
0
def browserid_authenticate(request, assertion):
    """
    Verify a BrowserID login attempt. If the BrowserID assertion is
    good, but no account exists on AMO, create one.

    Request is only needed for logging. :(
    """
    backend = BrowserIDBackend()
    result = backend.verify(assertion, settings.SITE_URL)
    if not result:
        return (None, None)
    email = result['email']
    users = UserProfile.objects.filter(email=email)
    if len(users) == 1:
        users[0].user.backend = 'django_browserid.auth.BrowserIDBackend'
        return (users[0], None)
    username = autocreate_username(email.partition('@')[0])
    if (settings.REGISTER_USER_LIMIT and
        UserProfile.objects.count() > settings.REGISTER_USER_LIMIT
        and not can_override_reg_limit(request)):
        _m = ('Sorry, no more registrations are allowed. '
              '<a href="https://developer.mozilla.org/en-US/apps">'
              'Learn more</a>')
        return (None, _m)
    profile = UserProfile.objects.create(username=username, email=email)
    profile.create_django_user()
    profile.user.backend = 'django_browserid.auth.BrowserIDBackend'
    profile.user.save()
    profile.save()
    log_cef('New Account', 5, request, username=username,
            signature='AUTHNOTICE',
            msg='User created a new account (from BrowserID)')
    return (profile, None)
Esempio n. 10
0
def cspreport(request):
    """Accept CSP reports and log them."""
    report = ("blocked-uri", "violated-directive", "original-policy")

    if not waffle.sample_is_active("csp-store-reports"):
        return HttpResponse()

    try:
        v = json.loads(request.body)["csp-report"]
        # If possible, alter the PATH_INFO to contain the request of the page
        # the error occurred on, spec: http://mzl.la/P82R5y
        meta = request.META.copy()
        meta["PATH_INFO"] = v.get("document-uri", meta["PATH_INFO"])
        v = [(k, v[k]) for k in report if k in v]
        log_cef(
            "CSPViolation",
            5,
            meta,
            username=request.user,
            signature="CSPREPORT",
            msg="A client reported a CSP violation",
            cs6=v,
            cs6Label="ContentPolicy",
        )
    except (KeyError, ValueError), e:
        log.debug("Exception in CSP report: %s" % e, exc_info=True)
        return HttpResponseBadRequest()
Esempio n. 11
0
def _fxa_authorize(fxa, client_secret, request, auth_response):
    token = fxa.fetch_token(
        fxa_oauth_api('token'),
        authorization_response=auth_response,
        client_secret=client_secret)
    res = fxa.post(fxa_oauth_api('verify'),
                   data=json.dumps({'token': token['access_token']}),
                   headers={'Content-Type': 'application/json'})
    data = res.json()
    if 'user' in data:
        email = data['email']
        username = data['user']
        try:
            profile = UserProfile.objects.get(email=email)
        except UserProfile.DoesNotExist:
            source = amo.LOGIN_SOURCE_FXA
            profile = UserProfile.objects.create(
                username=username,
                email=email,
                source=source,
                display_name=email.partition('@')[0],
                is_verified=True)
            log_cef('New Account', 5, request, username=username,
                    signature='AUTHNOTICE',
                    msg='User created a new account (from FxA)')
            record_action('new-user', request)
        auth.login(request, profile)
        profile.log_login_attempt(True)
        auth.signals.user_logged_in.send(
            sender=profile.__class__, request=request,
            user=profile)
        return profile
Esempio n. 12
0
def cspreport(request):
    """Accept CSP reports and log them."""
    report = ("blocked-uri", "violated-directive", "original-policy")

    if not waffle.sample_is_active("csp-store-reports"):
        return HttpResponse()

    try:
        v = json.loads(request.raw_post_data)["csp-report"]
        # CEF module wants a dictionary of environ, we want request
        # to be the page with error on it, that's contained in the csp-report
        # so we need to modify the meta before we pass in to the logger
        meta = request.META.copy()
        method, url = v["request"].split(" ", 1)
        meta.update({"REQUEST_METHOD": method, "PATH_INFO": url})
        v = [(k, v[k]) for k in report if k in v]
        log_cef(
            "CSP Violation",
            5,
            meta,
            username=request.user,
            signature="CSPREPORT",
            msg="A client reported a CSP violation",
            cs7=v,
            cs7Label="ContentPolicy",
        )
    except Exception, e:
        log.debug("Exception in CSP report: %s" % e, exc_info=True)
        return HttpResponseBadRequest()
Esempio n. 13
0
def cspreport(request):
    """Accept CSP reports and log them."""
    report = ('blocked-uri', 'violated-directive', 'original-policy')

    if not waffle.sample_is_active('csp-store-reports'):
        return HttpResponse()

    try:
        v = json.loads(request.body)['csp-report']
        # If possible, alter the PATH_INFO to contain the request of the page
        # the error occurred on, spec: http://mzl.la/P82R5y
        meta = request.META.copy()
        meta['PATH_INFO'] = v.get('document-uri', meta['PATH_INFO'])
        v = [(k, v[k]) for k in report if k in v]
        log_cef('CSP Violation',
                5,
                meta,
                username=request.user,
                signature='CSPREPORT',
                msg='A client reported a CSP violation',
                cs6=v,
                cs6Label='ContentPolicy')
    except (KeyError, ValueError), e:
        log.debug('Exception in CSP report: %s' % e, exc_info=True)
        return HttpResponseBadRequest()
Esempio n. 14
0
    def save(self, log_for_developer=True):
        u = super(UserEditForm, self).save(commit=False)
        data = self.cleaned_data
        photo = data['photo']
        if photo:
            u.picture_type = 'image/png'
            tmp_destination = u.picture_path + '__unconverted'

            with storage.open(tmp_destination, 'wb') as fh:
                for chunk in photo.chunks():
                    fh.write(chunk)

            tasks.resize_photo.delay(tmp_destination, u.picture_path,
                                     set_modified_on=[u])

        if data['password']:
            u.set_password(data['password'])
            log_cef('Password Changed', 5, self.request, username=u.username,
                    signature='PASSWORDCHANGED', msg='User changed password')
            if log_for_developer:
                amo.log(amo.LOG.CHANGE_PASSWORD)
                log.info(u'User (%s) changed their password' % u)

        for (i, n) in email.NOTIFICATIONS_BY_ID.items():
            enabled = n.mandatory or (str(i) in data['notifications'])
            UserNotification.update_or_create(user=u, notification_id=i,
                    update={'enabled': enabled})

        log.debug(u'User (%s) updated their profile' % u)

        u.save()
        return u
Esempio n. 15
0
File: views.py Progetto: vdt/zamboni
def cspreport(request):
    """Accept CSP reports and log them."""
    report = ('blocked-uri', 'violated-directive', 'original-policy')

    if not waffle.sample_is_active('csp-store-reports'):
        return HttpResponse()

    try:
        v = json.loads(request.raw_post_data)['csp-report']
        # CEF module wants a dictionary of environ, we want request
        # to be the page with error on it, that's contained in the csp-report
        # so we need to modify the meta before we pass in to the logger
        meta = request.META.copy()
        method, url = v['request'].split(' ', 1)
        meta.update({'REQUEST_METHOD': method, 'PATH_INFO': url})
        v = [(k, v[k]) for k in report if k in v]
        log_cef('CSP Violation',
                5,
                meta,
                username=request.user,
                signature='CSPREPORT',
                msg='A client reported a CSP violation',
                cs7=v,
                cs7Label='ContentPolicy')
    except Exception, e:
        log.debug('Exception in CSP report: %s' % e, exc_info=True)
        return HttpResponseBadRequest()
Esempio n. 16
0
    def save(self, log_for_developer=True):
        u = super(UserEditForm, self).save(commit=False)
        data = self.cleaned_data
        photo = data['photo']
        if photo:
            u.picture_type = 'image/png'
            tmp_destination = u.picture_path + '__unconverted'

            with storage.open(tmp_destination, 'wb') as fh:
                for chunk in photo.chunks():
                    fh.write(chunk)

            tasks.resize_photo.delay(tmp_destination, u.picture_path,
                                     set_modified_on=[u])

        if data['password']:
            u.set_password(data['password'])
            log_cef('Password Changed', 5, self.request, username=u.username,
                    signature='PASSWORDCHANGED', msg='User changed password')
            if log_for_developer:
                amo.log(amo.LOG.CHANGE_PASSWORD)
                log.info(u'User (%s) changed their password' % u)

        for (i, n) in email.NOTIFICATIONS_BY_ID.items():
            enabled = n.mandatory or (str(i) in data['notifications'])
            UserNotification.update_or_create(user=u, notification_id=i,
                    update={'enabled': enabled})

        log.debug(u'User (%s) updated their profile' % u)

        u.save()
        return u
Esempio n. 17
0
 def save(self, **kw):
     # Three different loggers? :(
     amo.log(amo.LOG.CHANGE_PASSWORD, user=self.user)
     log.info(u'User (%s) changed password with reset form' % self.user)
     log_cef('Password Changed', 5, self.request,
             username=self.user.username, signature='PASSWORDCHANGED',
             msg='User changed password')
     super(SetPasswordForm, self).save(**kw)
Esempio n. 18
0
 def save(self, **kw):
     # Three different loggers? :(
     amo.log(amo.LOG.CHANGE_PASSWORD, user=self.user)
     log.info(u'User (%s) changed password with reset form' % self.user)
     log_cef('Password Changed', 5, self.request,
             username=self.user.username, signature='PASSWORDCHANGED',
             msg='User changed password')
     super(SetPasswordForm, self).save(**kw)
Esempio n. 19
0
def register(request):

    if request.user.is_authenticated():
        messages.info(request, _('You are already logged in to an account.'))
        form = None

    elif request.method == 'POST':

        form = forms.UserRegisterForm(request.POST)
        mkt_user = UserProfile.objects.filter(email=form.data['email'],
                                              password='')
        if form.is_valid():
            try:
                u = form.save(commit=False)
                u.set_password(form.cleaned_data['password'])
                u.generate_confirmationcode()
                u.lang = request.LANG
                u.save()
                log.info(u'Registered new account for user (%s)', u)
                log_cef('New Account',
                        5,
                        request,
                        username=u.username,
                        signature='AUTHNOTICE',
                        msg='User created a new account')

                u.email_confirmation_code()

                msg = _('Congratulations! Your user account was '
                        'successfully created.')
                messages.success(request, msg)

                msg = _(u'An email has been sent to your address {0} to '
                        'confirm your account. Before you can log in, you '
                        'have to activate your account by clicking on the '
                        'link provided in this email.').format(u.email)
                messages.info(request, _('Confirmation Email Sent'), msg)

            except IntegrityError, e:
                # I was unable to reproduce this, but I suspect it happens
                # when they POST twice quickly and the slaves don't have the
                # new info yet (total guess).  Anyway, I'm assuming the
                # first one worked properly, so this is still a success
                # case to the end user so we just log it...
                log.error('Failed to register new user (%s): %s' % (u, e))

            return http.HttpResponseRedirect(reverse('users.login'))

        elif mkt_user.exists():
            f = PasswordResetForm()
            f.users_cache = [mkt_user[0]]
            f.save(use_https=request.is_secure(),
                   email_template_name='users/email/pwreset.ltxt',
                   request=request)
            return render(request, 'users/newpw_sent.html', {})
        else:
            messages.error(request, _('There are errors in this form'),
                           _('Please correct them and resubmit.'))
Esempio n. 20
0
def _login(request, template=None, data=None, dont_redirect=False):
    data = data or {}
    data['webapp'] = True
    # In case we need it later.  See below.
    get_copy = request.GET.copy()

    if 'to' in request.GET:
        request = _clean_next_url(request)

    if request.user.is_authenticated():
        return http.HttpResponseRedirect(
            request.GET.get('to', settings.LOGIN_REDIRECT_URL))

    user = None
    login_status = None
    r = auth_login(request, template_name=template, redirect_field_name='to',
                   extra_context=data)

    if isinstance(r, http.HttpResponseRedirect):
        # Django's auth.views.login has security checks to prevent someone from
        # redirecting to another domain.  Since we want to allow this in
        # certain cases, we have to make a new response object here to replace
        # the above.

        if 'domain' in request.GET:
            request.GET = get_copy
            request = _clean_next_url(request)
            r = http.HttpResponseRedirect(request.GET['to'])

        # Succsesful log in according to django.  Now we do our checks.  I do
        # the checks here instead of the form's clean() because I want to use
        # the messages framework and it's not available in the request there.
        if user.deleted:
            logout(request)
            log.warning(u'Attempt to log in with deleted account (%s)' % user)
            messages.error(request, _('Wrong email address or password!'))
            user.log_login_attempt(False)
            log_cef('Authentication Failure', 5, request,
                    username=request.user, signature='AUTHFAIL',
                    msg='Account is deactivated')
            return render(request, template, data)

        login_status = True

        if dont_redirect:
            # We're recalling the middleware to re-initialize amo_user
            ACLMiddleware().process_request(request)
            r = render(request, template, data)

    if login_status is not None:
        user.log_login_attempt(login_status)
        log_cef('Authentication Failure', 5, request,
                username=request.POST['username'],
                signature='AUTHFAIL',
                msg='The password was incorrect')

    return r
Esempio n. 21
0
def browserid_authenticate(request, assertion, is_mobile=False,
                           browserid_audience=get_audience):
    """
    Verify a BrowserID login attempt. If the BrowserID assertion is
    good, but no account exists, create one.

    """
    extra_params = {}
    url = settings.NATIVE_FXA_VERIFICATION_URL
    log.debug('Verifying Native FxA at %s, audience: %s, '
              'extra_params: %s' % (url, browserid_audience, extra_params))
    v = BrowserIDBackend().get_verifier()
    v.verification_service_url = url
    result = v.verify(assertion, browserid_audience, url=url, **extra_params)
    if not result:
        return None, _('Native FxA authentication failure.')

    if 'unverified-email' in result._response:
        email = result._response['unverified-email']
        verified = False
    elif (result._response.get('issuer') == settings.NATIVE_FXA_ISSUER and
          'fxa-verifiedEmail' in result._response.get('idpClaims', {})):
        email = result._response['idpClaims']['fxa-verifiedEmail']
        verified = True
    else:
        email = result.email
        verified = True

    try:
        profile = UserProfile.objects.filter(email=email)[0]
    except IndexError:
        profile = None

    if profile:
        if profile.is_verified and not verified:
            # An attempt to log in to a verified address with an unverified
            # assertion is a very bad thing. Don't let that happen.
            log.debug('Verified user %s attempted to log in with an '
                      'unverified assertion!' % profile)
            return None, _('Please use the verified email for this account.')
        else:
            profile.is_verified = verified
            profile.save()

        return profile, None

    username = autocreate_username(email.partition('@')[0])
    source = amo.LOGIN_SOURCE_MMO_BROWSERID
    profile = UserProfile.objects.create(username=username, email=email,
                                         source=source, display_name=username,
                                         is_verified=verified)
    log_cef('New Account', 5, request, username=username,
            signature='AUTHNOTICE',
            msg='User created a new account (from Persona)')
    record_action('new-user', request)

    return profile, None
Esempio n. 22
0
def register(request):
    if waffle.switch_is_active('fxa-auth'):
        return login(request)

    if request.user.is_authenticated():
        messages.info(request, _('You are already logged in to an account.'))
        form = None

    elif request.method == 'POST':

        form = forms.UserRegisterForm(request.POST)
        mkt_user = UserProfile.objects.filter(email=form.data['email'],
                                              password='')
        if form.is_valid():
            try:
                u = form.save(commit=False)
                u.set_password(form.cleaned_data['password'])
                u.generate_confirmationcode()
                u.lang = request.LANG
                u.save()
                log.info(u'Registered new account for user (%s)', u)
                log_cef('New Account', 5, request, username=u.username,
                        signature='AUTHNOTICE',
                        msg='User created a new account')

                u.email_confirmation_code()

                msg = _('Congratulations! Your user account was '
                        'successfully created.')
                messages.success(request, msg)

                msg = _(u'An email has been sent to your address {0} to '
                        'confirm your account. Before you can log in, you '
                        'have to activate your account by clicking on the '
                        'link provided in this email.').format(u.email)
                messages.info(request, _('Confirmation Email Sent'), msg)

            except IntegrityError, e:
                # I was unable to reproduce this, but I suspect it happens
                # when they POST twice quickly and the slaves don't have the
                # new info yet (total guess).  Anyway, I'm assuming the
                # first one worked properly, so this is still a success
                # case to the end user so we just log it...
                log.error('Failed to register new user (%s): %s' % (u, e))

            return http.HttpResponseRedirect(reverse('users.login'))

        elif mkt_user.exists():
            f = PasswordResetForm()
            f.users_cache = [mkt_user[0]]
            f.save(use_https=request.is_secure(),
                   email_template_name='users/email/pwreset.ltxt',
                   request=request)
            return render(request, 'users/newpw_sent.html', {})
        else:
            messages.error(request, _('There are errors in this form'),
                           _('Please correct them and resubmit.'))
Esempio n. 23
0
def paypal_log_cef(request, addon, uuid, msg, caps, longer):
    log_cef('Paypal %s' % msg,
            5,
            request,
            username=request.amo_user,
            signature='PAYPAL%s' % caps,
            msg=longer,
            cs2=addon.name,
            cs2Label='PaypalTransaction',
            cs4=uuid,
            cs4Label='TxID')
Esempio n. 24
0
def paypal_log_cef(request, addon, uuid, msg, caps, longer):
    log_cef(
        "Paypal %s" % msg,
        5,
        request,
        username=request.amo_user,
        signature="PAYPAL%s" % caps,
        msg=longer,
        cs2=addon.name,
        cs2Label="PaypalTransaction",
        cs4=uuid,
        cs4Label="TxID",
    )
Esempio n. 25
0
def _fxa_authorize(fxa, client_secret, request, auth_response, userid):
    token = fxa.fetch_token(fxa_oauth_api('token'),
                            authorization_response=auth_response,
                            client_secret=client_secret)
    res = fxa.post(fxa_oauth_api('verify'),
                   data=json.dumps({'token': token['access_token']}),
                   headers={'Content-Type': 'application/json'})
    data = res.json()

    if 'user' in data:
        email = data['email']
        fxa_uid = data['user']

        def find_user(**kwargs):
            try:
                return UserProfile.objects.get(**kwargs)
            except UserProfile.DoesNotExist:
                return None

        profile = (find_user(pk=userid) or find_user(username=fxa_uid)
                   or find_user(email=email))
        if profile:
            profile.update(username=fxa_uid, email=email)
        else:
            profile = UserProfile.objects.create(
                username=fxa_uid,
                email=email,
                source=amo.LOGIN_SOURCE_FXA,
                display_name=email.partition('@')[0],
                is_verified=True)
            log_cef('New Account',
                    5,
                    request,
                    username=fxa_uid,
                    signature='AUTHNOTICE',
                    msg='User created a new account (from FxA)')
            record_action('new-user', request)

        if profile.source != amo.LOGIN_SOURCE_FXA:
            profile.update(source=amo.LOGIN_SOURCE_FXA)

        auth.login(request, profile)
        profile.log_login_attempt(True)

        auth.signals.user_logged_in.send(sender=profile.__class__,
                                         request=request,
                                         user=profile)

        return profile
Esempio n. 26
0
    def explode(self):
        error = self.cleaned_data.get('error')

        if error == 'zerodivisionerror':
            1 / 0
        elif error == 'iorequesterror':
            class IOError(Exception):
                pass
            raise IOError('request data read error')
        elif error == 'heka_cef':
            environ = {'REMOTE_ADDR': '127.0.0.1', 'HTTP_HOST': '127.0.0.1',
                       'PATH_INFO': '/', 'REQUEST_METHOD': 'GET',
                       'HTTP_USER_AGENT': 'MySuperBrowser'}

            config = {'cef.version': '0',
                      'cef.vendor': 'Mozilla',
                      'cef.device_version': '3',
                      'cef.product': 'zamboni',
                      'cef': True}

            settings.HEKA.cef(
                'xx\nx|xx\rx', 5, environ, config,
                username='******', ext1='ok=ok', ext2='ok\\ok',
                logger_info='settings.HEKA')
        elif error == 'heka_statsd':
            settings.HEKA.incr(name=LOGGER_NAME)
        elif error == 'heka_json':
            settings.HEKA.heka(
                type="heka_json",
                fields={'foo': 'bar', 'secret': 42,
                        'logger_type': 'settings.HEKA'})

        elif error == 'heka_sentry':
            # These are local variables only used
            # by Sentry's frame hacking magic.
            # They won't be referenced which may trigger flake8
            # errors.
            heka_conf = settings.HEKA_CONF  # NOQA
            active_heka_conf = settings.HEKA._config  # NOQA
            try:
                1 / 0
            except:
                settings.HEKA.raven('heka_sentry error triggered')
        elif error == 'amo_cef':
            from amo.utils import log_cef
            env = {'REMOTE_ADDR': '127.0.0.1', 'HTTP_HOST': '127.0.0.1',
                   'PATH_INFO': '/', 'REQUEST_METHOD': 'GET',
                   'HTTP_USER_AGENT': 'MySuperBrowser'}
            log_cef(settings.STATSD_PREFIX, 6, env)
Esempio n. 27
0
def _fxa_authorize(fxa, client_secret, request, auth_response, userid):
    token = fxa.fetch_token(
        fxa_oauth_api('token'),
        authorization_response=auth_response,
        client_secret=client_secret)
    res = fxa.post(fxa_oauth_api('verify'),
                   data=json.dumps({'token': token['access_token']}),
                   headers={'Content-Type': 'application/json'})
    data = res.json()

    if 'user' in data:
        email = data['email']
        fxa_uid = data['user']

        def find_user(**kwargs):
            try:
                return UserProfile.objects.get(**kwargs)
            except UserProfile.DoesNotExist:
                return None

        profile = (find_user(pk=userid) or find_user(username=fxa_uid)
                   or find_user(email=email))
        if profile:
            profile.update(username=fxa_uid, email=email)
        else:
            profile = UserProfile.objects.create(
                username=fxa_uid,
                email=email,
                source=amo.LOGIN_SOURCE_FXA,
                display_name=email.partition('@')[0],
                is_verified=True)
            log_cef('New Account', 5, request, username=fxa_uid,
                    signature='AUTHNOTICE',
                    msg='User created a new account (from FxA)')
            record_action('new-user', request)

        if profile.source != amo.LOGIN_SOURCE_FXA:
            log.info('Set account to FxA for {0}'.format(email))
            statsd.incr('z.mkt.user.fxa')
            profile.update(source=amo.LOGIN_SOURCE_FXA)

        auth.login(request, profile)
        profile.log_login_attempt(True)

        auth.signals.user_logged_in.send(sender=profile.__class__,
                                         request=request, user=profile)

        return profile
Esempio n. 28
0
def browserid_authenticate(request, assertion):
    """
    Verify a BrowserID login attempt. If the BrowserID assertion is
    good, but no account exists on AMO, create one.

    Request is only needed for logging. :(
    """
    backend = BrowserIDBackend()
    result = backend.verify(assertion, settings.SITE_URL)
    if not result:
        return (None, "BrowserID authentication failure.")
    email = result["email"]
    users = UserProfile.objects.filter(email=email)
    if len(users) == 1:
        users[0].user.backend = "django_browserid.auth.BrowserIDBackend"
        return (users[0], None)
    username = autocreate_username(email.partition("@")[0])
    if (
        settings.REGISTER_USER_LIMIT
        and UserProfile.objects.count() > settings.REGISTER_USER_LIMIT
        and not can_override_reg_limit(request)
    ):
        _m = (
            "Sorry, no more registrations are allowed. "
            '<a href="https://developer.mozilla.org/en-US/apps">'
            "Learn more</a>"
        )
        return (None, _m)
    profile = UserProfile.objects.create(
        username=username, email=email, source=amo.LOGIN_SOURCE_BROWSERID, display_name=username
    )

    profile.create_django_user()
    profile.user.backend = "django_browserid.auth.BrowserIDBackend"
    if settings.APP_PREVIEW:
        profile.notes = "__market__"
    profile.user.save()
    profile.save()
    log_cef(
        "New Account",
        5,
        request,
        username=username,
        signature="AUTHNOTICE",
        msg="User created a new account (from BrowserID)",
    )
    return (profile, None)
Esempio n. 29
0
 def save(self, *args, **kw):
     profile = super(AdminUserEditForm, self).save(log_for_developer=False)
     if self.cleaned_data['anonymize']:
         amo.log(amo.LOG.ADMIN_USER_ANONYMIZED, self.instance,
                 self.cleaned_data['admin_log'])
         profile.anonymize()  # This also logs
     else:
         amo.log(amo.LOG.ADMIN_USER_EDITED, self.instance,
                 self.cleaned_data['admin_log'], details=self.changes())
         log.info('Admin edit user: %s changed fields: %s' %
                  (self.instance, self.changed_fields()))
         if 'password' in self.changes():
             log_cef('Password Changed', 5, self.request,
                     username=self.instance.username,
                     signature='PASSWORDRESET',
                     msg='Admin requested password reset',
                     cs1=self.request.amo_user.username,
                     cs1Label='AdminName')
     return profile
Esempio n. 30
0
 def save(self, *args, **kw):
     profile = super(AdminUserEditForm, self).save(log_for_developer=False)
     if self.cleaned_data['anonymize']:
         amo.log(amo.LOG.ADMIN_USER_ANONYMIZED, self.instance,
                 self.cleaned_data['admin_log'])
         profile.anonymize()  # This also logs
     else:
         amo.log(amo.LOG.ADMIN_USER_EDITED, self.instance,
                 self.cleaned_data['admin_log'], details=self.changes())
         log.info('Admin edit user: %s changed fields: %s' %
                  (self.instance, self.changed_fields()))
         if 'password' in self.changes():
             log_cef('Password Changed', 5, self.request,
                     username=self.instance.username,
                     signature='PASSWORDRESET',
                     msg='Admin requested password reset',
                     cs1=self.request.amo_user.username,
                     cs1Label='AdminName')
     return profile
Esempio n. 31
0
 def save(self, *args, **kw):
     profile = super(AdminUserEditForm, self).save(log_for_developer=False)
     if self.cleaned_data["anonymize"]:
         amo.log(amo.LOG.ADMIN_USER_ANONYMIZED, self.instance, self.cleaned_data["admin_log"])
         profile.anonymize()  # This also logs
     else:
         amo.log(amo.LOG.ADMIN_USER_EDITED, self.instance, self.cleaned_data["admin_log"], details=self.changes())
         log.info("Admin edit user: %s changed fields: %s" % (self.instance, self.changed_fields()))
         if "password" in self.changes():
             log_cef(
                 "Password Changed",
                 5,
                 self.request,
                 username=self.instance.username,
                 signature="PASSWORDRESET",
                 msg="Admin requested password reset",
                 cs1=self.request.amo_user.username,
                 cs1Label="AdminName",
             )
     return profile
Esempio n. 32
0
def cspreport(request):
    """Accept CSP reports and log them."""
    report = ('blocked-uri', 'violated-directive', 'original-policy')

    if not waffle.sample_is_active('csp-store-reports'):
        return HttpResponse()

    try:
        v = json.loads(request.body)['csp-report']
        # If possible, alter the PATH_INFO to contain the request of the page
        # the error occurred on, spec: http://mzl.la/P82R5y
        meta = request.META.copy()
        meta['PATH_INFO'] = v.get('document-uri', meta['PATH_INFO'])
        v = [(k, v[k]) for k in report if k in v]
        log_cef('CSP Violation', 5, meta, username=request.user,
                signature='CSPREPORT',
                msg='A client reported a CSP violation',
                cs6=v, cs6Label='ContentPolicy')
    except (KeyError, ValueError), e:
        log.debug('Exception in CSP report: %s' % e, exc_info=True)
        return HttpResponseBadRequest()
Esempio n. 33
0
 def save(self, **kw):
     if not self.users_cache:
         log.info("Unknown email used for password reset: {email}".format(**self.cleaned_data))
         return
     for user in self.users_cache:
         log.info(u'Password reset email sent for user (%s)' % user)
         if user.needs_tougher_password:
             log_cef('Password Reset', 5, self.request,
                     username=user,
                     signature='PASSWORDRESET',
                     msg='Privileged user requested password reset')
         else:
             log_cef('Password Reset', 5, self.request,
                     username=user,
                     signature='PASSWORDRESET',
                     msg='User requested password reset')
     try:
         # Django calls send_mail() directly and has no option to pass
         # in fail_silently, so we have to catch the SMTP error ourselves
         self.base_save(**kw)
     except SMTPException, e:
         log.error("Failed to send mail for (%s): %s" % (user, e))
Esempio n. 34
0
def cspreport(request):
    """Accept CSP reports and log them."""
    report = ('blocked-uri', 'violated-directive', 'original-policy')

    if not waffle.sample_is_active('csp-store-reports'):
        return HttpResponse()

    try:
        v = json.loads(request.raw_post_data)['csp-report']
        # CEF module wants a dictionary of environ, we want request
        # to be the page with error on it, that's contained in the csp-report
        # so we need to modify the meta before we pass in to the logger
        meta = request.META.copy()
        method, url = v['request'].split(' ', 1)
        meta.update({'REQUEST_METHOD': method, 'PATH_INFO': url})
        v = [(k, v[k]) for k in report if k in v]
        log_cef('CSP Violation', 5, meta, username=request.user,
                signature='CSPREPORT',
                msg='A client reported a CSP violation',
                cs7=v, cs7Label='ContentPolicy')
    except Exception, e:
        log.debug('Exception in CSP report: %s' % e, exc_info=True)
        return HttpResponseBadRequest()
Esempio n. 35
0
    def create_action(self, request, serializer):
        client_id = request.POST.get('client_id', settings.FXA_CLIENT_ID)
        secret = settings.FXA_SECRETS[client_id]
        session = OAuth2Session(client_id,
                                scope=u'profile',
                                state=serializer.data['state'])

        try:
            # Maybe this was a preverified login to migrate a user.
            userid = Signer().unsign(serializer.data['state'])
        except BadSignature:
            userid = None

        auth_response = serializer.data['auth_response']
        fxa_authorization = fxa_authorize(session, secret, auth_response)

        if 'user' in fxa_authorization:
            email = fxa_authorization['email']
            fxa_uid = fxa_authorization['user']
            profile, created = find_or_create_user(email, fxa_uid, userid)
            if created:
                log_cef('New Account',
                        5,
                        request,
                        username=fxa_uid,
                        signature='AUTHNOTICE',
                        msg='User created a new account (from FxA)')
                record_action('new-user', request)
            auth.login(request, profile)
            profile.log_login_attempt(True)

            auth.signals.user_logged_in.send(sender=profile.__class__,
                                             request=request,
                                             user=profile)
        else:
            raise AuthenticationFailed('No profile.')

        request.user = profile
        request.groups = profile.groups.all()
        # Remember whether the user has logged in to highlight the register or
        # sign in nav button. 31536000 == one year.
        request.set_cookie('has_logged_in', '1', max_age=5 * 31536000)

        # We want to return completely custom data, not the serializer's.
        data = {
            'error': None,
            'token': commonplace_token(request.user.email),
            'settings': {
                'display_name': request.user.display_name,
                'email': request.user.email,
                'enable_recommendations': request.user.enable_recommendations,
                'source': 'firefox-accounts',
            }
        }
        # Serializers give up if they aren't passed an instance, so we
        # do that here despite PermissionsSerializer not needing one
        # really.
        permissions = PermissionsSerializer(context={'request': request},
                                            instance=True)
        data.update(permissions.data)

        # Add ids of installed/purchased/developed apps.
        data['apps'] = user_relevant_apps(profile)

        return data
Esempio n. 36
0
def browserid_authenticate(request,
                           assertion,
                           is_mobile=False,
                           browserid_audience=get_audience):
    """
    Verify a BrowserID login attempt. If the BrowserID assertion is
    good, but no account exists, create one.

    """
    extra_params = {}
    url = settings.NATIVE_FXA_VERIFICATION_URL
    log.debug('Verifying Native FxA at %s, audience: %s, '
              'extra_params: %s' % (url, browserid_audience, extra_params))
    v = BrowserIDBackend().get_verifier()
    v.verification_service_url = url
    result = v.verify(assertion, browserid_audience, url=url, **extra_params)
    if not result:
        return None, _('Native FxA authentication failure.')

    if 'unverified-email' in result._response:
        email = result._response['unverified-email']
        verified = False
    elif (result._response.get('issuer') == settings.NATIVE_FXA_ISSUER
          and 'fxa-verifiedEmail' in result._response.get('idpClaims', {})):
        email = result._response['idpClaims']['fxa-verifiedEmail']
        verified = True
    else:
        email = result.email
        verified = True

    try:
        profile = UserProfile.objects.filter(email=email)[0]
    except IndexError:
        profile = None

    if profile:
        if profile.is_verified and not verified:
            # An attempt to log in to a verified address with an unverified
            # assertion is a very bad thing. Don't let that happen.
            log.debug('Verified user %s attempted to log in with an '
                      'unverified assertion!' % profile)
            return None, _('Please use the verified email for this account.')
        else:
            profile.is_verified = verified
            profile.save()

        return profile, None

    username = autocreate_username(email.partition('@')[0])
    source = amo.LOGIN_SOURCE_MMO_BROWSERID
    profile = UserProfile.objects.create(username=username,
                                         email=email,
                                         source=source,
                                         display_name=username,
                                         is_verified=verified)
    log_cef('New Account',
            5,
            request,
            username=username,
            signature='AUTHNOTICE',
            msg='User created a new account (from Persona)')
    record_action('new-user', request)

    return profile, None
Esempio n. 37
0
def _login(request, template=None, data=None, dont_redirect=False):
    data = data or {}
    # In case we need it later.  See below.
    get_copy = request.GET.copy()

    if 'to' in request.GET:
        request = _clean_next_url(request)

    if request.user.is_authenticated():
        return http.HttpResponseRedirect(
            request.GET.get('to', settings.LOGIN_REDIRECT_URL))

    limited = getattr(request, 'limited', 'recaptcha_shown' in request.POST)
    user = None
    login_status = None
    if 'username' in request.POST:
        try:
            # We are doing all this before we try and validate the form.
            user = UserProfile.objects.get(email=request.POST['username'])
            limited = (
                (user.failed_login_attempts >= settings.LOGIN_RATELIMIT_USER)
                or limited)
            login_status = False
        except UserProfile.DoesNotExist:
            log_cef('Authentication Failure',
                    5,
                    request,
                    username=request.POST['username'],
                    signature='AUTHFAIL',
                    msg='The username was invalid')
            pass
    partial_form = partial(forms.AuthenticationForm, use_recaptcha=limited)
    r = auth.views.login(request,
                         template_name=template,
                         redirect_field_name='to',
                         authentication_form=partial_form,
                         extra_context=data)

    if isinstance(r, http.HttpResponseRedirect):
        # Django's auth.views.login has security checks to prevent someone from
        # redirecting to another domain.  Since we want to allow this in
        # certain cases, we have to make a new response object here to replace
        # the above.

        if 'domain' in request.GET:
            request.GET = get_copy
            request = _clean_next_url(request)
            r = http.HttpResponseRedirect(request.GET['to'])

        # Succsesful log in according to django.  Now we do our checks.  I do
        # the checks here instead of the form's clean() because I want to use
        # the messages framework and it's not available in the request there.
        if user.deleted:
            logout(request)
            log.warning(u'Attempt to log in with deleted account (%s)' % user)
            messages.error(request, _('Wrong email address or password!'))
            data.update({'form': partial_form()})
            user.log_login_attempt(False)
            log_cef('Authentication Failure',
                    5,
                    request,
                    username=request.user,
                    signature='AUTHFAIL',
                    msg='Account is deactivated')
            return render(request, template, data)

        if user.confirmationcode:
            logout(request)
            log.info(u'Attempt to log in with unconfirmed account (%s)' % user)
            msg1 = _(u'A link to activate your user account was sent by email '
                     u'to your address {0}. You have to click it before you '
                     u'can log in.').format(user.email)
            url = "%s%s" % (settings.SITE_URL,
                            reverse('users.confirm.resend', args=[user.id]))
            msg2 = _('If you did not receive the confirmation email, make '
                     'sure your email service did not mark it as "junk '
                     'mail" or "spam". If you need to, you can have us '
                     '<a href="%s">resend the confirmation message</a> '
                     'to your email address mentioned above.') % url
            messages.error(request, _('Activation Email Sent'), msg1)
            messages.info(request,
                          _('Having Trouble?'),
                          msg2,
                          title_safe=True,
                          message_safe=True)
            data.update({'form': partial_form()})
            user.log_login_attempt(False)
            return render(request, template, data)

        rememberme = request.POST.get('rememberme', None)
        if rememberme:
            request.session.set_expiry(settings.SESSION_COOKIE_AGE)
            log.debug(
                u'User (%s) logged in successfully with "remember me" set' %
                user)

        login_status = True

        if dont_redirect:
            # We're recalling the middleware to re-initialize amo_user
            ACLMiddleware().process_request(request)
            r = render(request, template, data)

    if login_status is not None:
        user.log_login_attempt(login_status)
        log_cef('Authentication Failure',
                5,
                request,
                username=request.POST['username'],
                signature='AUTHFAIL',
                msg='The password was incorrect')

    return r
Esempio n. 38
0
def browserid_authenticate(request,
                           assertion,
                           is_mobile=False,
                           browserid_audience=get_audience):
    """
    Verify a BrowserID login attempt. If the BrowserID assertion is
    good, but no account exists, create one.

    """
    url = settings.BROWSERID_VERIFICATION_URL

    # We must always force the Firefox OS identity provider. This is because
    # we are sometimes allowing unverified assertions and you can't mix that
    # feature with bridged IdPs. See bug 910938.
    extra_params = {}
    if settings.UNVERIFIED_ISSUER:
        extra_params['experimental_forceIssuer'] = settings.UNVERIFIED_ISSUER

    if is_mobile:
        # When persona is running in a mobile OS then we can allow unverified
        # assertions.
        url = settings.NATIVE_BROWSERID_VERIFICATION_URL
        extra_params['experimental_allowUnverified'] = 'true'

    log.debug('Verifying Persona at %s, audience: %s, '
              'extra_params: %s' % (url, browserid_audience, extra_params))
    result = verify(assertion,
                    browserid_audience,
                    url=url,
                    extra_params=extra_params)
    if not result:
        return None, _('Persona authentication failure.')

    if 'unverified-email' in result:
        email = result['unverified-email']
        verified = False
    else:
        email = result['email']
        verified = True

    try:
        profile = UserProfile.objects.filter(email=email)[0]
    except IndexError:
        profile = None

    if profile:
        if profile.is_verified and not verified:
            # An attempt to log in to a verified address with an unverified
            # assertion is a very bad thing. Don't let that happen.
            log.debug('Verified user %s attempted to log in with an '
                      'unverified assertion!' % profile)
            return None, _('Please use the verified email for this account.')
        else:
            profile.is_verified = verified
            profile.save()

        return profile, None

    username = autocreate_username(email.partition('@')[0])
    source = amo.LOGIN_SOURCE_AMO_BROWSERID
    profile = UserProfile.objects.create(username=username,
                                         email=email,
                                         source=source,
                                         display_name=username,
                                         is_verified=verified)
    log_cef('New Account',
            5,
            request,
            username=username,
            signature='AUTHNOTICE',
            msg='User created a new account (from Persona)')
    return profile, None
Esempio n. 39
0
def browserid_authenticate(request, assertion, is_native=False):
    """
    Verify a BrowserID login attempt. If the BrowserID assertion is
    good, but no account exists, create one.

    """
    url = settings.BROWSERID_VERIFICATION_URL
    extra_params = None
    if is_native:
        # When persona is running native on B2G then we need to
        # verify assertions with the right service.
        # We also need to force the appropriate issuer
        # for potentially unverified emails.
        url = settings.NATIVE_BROWSERID_VERIFICATION_URL
        extra_params = {'issuer': settings.UNVERIFIED_ISSUER,
                        'allowUnverified': 'true'}

    audience = get_audience(request)
    log.debug('Verifying Persona at %s, audience: %s, '
              'extra_params: %s' % (url, audience, extra_params))
    result = verify(assertion, audience,
                    url=url, extra_params=extra_params)
    if not result:
        return None, _('Persona authentication failure.')

    if 'unverified-email' in result:
        email = result['unverified-email']
        verified = False
    else:
        email = result['email']
        verified = True

    try:
        profile = UserProfile.objects.filter(email=email)[0]
    except IndexError:
        profile = None

    if profile:
        if profile.is_verified and not verified:
            # An attempt to log in to a verified address with an unverified
            # assertion is a very bad thing. However, the same email address
            # can legitimately be used on the site on desktop and be verified
            # whilst be used on b2g and be unverified. We are forcing the
            # issuer, so this shouldn't be an issue.
            #
            # Blame kumar. Or cvan. Or deal with it.
            log.debug('Verified user %s attempted to log in with an '
                      'unverified assertion!' % profile)
        else:
            profile.is_verified = verified
            profile.save()

        backend = 'django_browserid.auth.BrowserIDBackend'
        if getattr(profile.user, 'backend', None) != backend:
            profile.user.backend = backend
            profile.user.save()

        return profile, None

    username = autocreate_username(email.partition('@')[0])
    source = (amo.LOGIN_SOURCE_MMO_BROWSERID if settings.MARKETPLACE else
              amo.LOGIN_SOURCE_AMO_BROWSERID)
    profile = UserProfile.objects.create(username=username, email=email,
                                         source=source, display_name=username,
                                         is_verified=verified)
    profile.create_django_user(
        backend='django_browserid.auth.BrowserIDBackend')
    log_cef('New Account', 5, request, username=username,
            signature='AUTHNOTICE',
            msg='User created a new account (from Persona)')
    return profile, None
Esempio n. 40
0
def browserid_authenticate(request, assertion, is_mobile=False, browserid_audience=get_audience):
    """
    Verify a BrowserID login attempt. If the BrowserID assertion is
    good, but no account exists, create one.

    """
    url = settings.BROWSERID_VERIFICATION_URL

    # We must always force the Firefox OS identity provider. This is because
    # we are sometimes allowing unverified assertions and you can't mix that
    # feature with bridged IdPs. See bug 910938.
    extra_params = {}
    if settings.UNVERIFIED_ISSUER:
        extra_params["experimental_forceIssuer"] = settings.UNVERIFIED_ISSUER

    if is_mobile:
        # When persona is running in a mobile OS then we can allow unverified
        # assertions.
        url = settings.NATIVE_BROWSERID_VERIFICATION_URL
        extra_params["experimental_allowUnverified"] = "true"

    log.debug("Verifying Persona at %s, audience: %s, " "extra_params: %s" % (url, browserid_audience, extra_params))
    result = verify(assertion, browserid_audience, url=url, extra_params=extra_params)
    if not result:
        return None, _("Persona authentication failure.")

    if "unverified-email" in result:
        email = result["unverified-email"]
        verified = False
    else:
        email = result["email"]
        verified = True

    try:
        profile = UserProfile.objects.filter(email=email)[0]
    except IndexError:
        profile = None

    if profile:
        # Added due to bug 905984. It's possible to have a UserProfile
        # that has no corresponding User object.
        if profile.user is None:
            profile.create_django_user(backend="django_browserid.auth.BrowserIDBackend")
        if profile.is_verified and not verified:
            # An attempt to log in to a verified address with an unverified
            # assertion is a very bad thing. Don't let that happen.
            log.debug("Verified user %s attempted to log in with an " "unverified assertion!" % profile)
            return None, _("Please use the verified email for this account.")
        else:
            profile.is_verified = verified
            profile.save()

        backend = "django_browserid.auth.BrowserIDBackend"
        if getattr(profile.user, "backend", None) != backend:
            profile.user.backend = backend
            profile.user.save()

        return profile, None

    username = autocreate_username(email.partition("@")[0])
    source = amo.LOGIN_SOURCE_MMO_BROWSERID if settings.MARKETPLACE else amo.LOGIN_SOURCE_AMO_BROWSERID
    profile = UserProfile.objects.create(
        username=username, email=email, source=source, display_name=username, is_verified=verified
    )
    profile.create_django_user(backend="django_browserid.auth.BrowserIDBackend")
    log_cef(
        "New Account",
        5,
        request,
        username=username,
        signature="AUTHNOTICE",
        msg="User created a new account (from Persona)",
    )
    if settings.MARKETPLACE:
        record_action("new-user", request)
    return profile, None
Esempio n. 41
0
def browserid_authenticate(request,
                           assertion,
                           is_mobile=False,
                           browserid_audience=get_audience):
    """
    Verify a BrowserID login attempt. If the BrowserID assertion is
    good, but no account exists, create one.

    """
    url = settings.BROWSERID_VERIFICATION_URL

    # We must always force the Firefox OS identity provider. This is because
    # we are sometimes allowing unverified assertions and you can't mix that
    # feature with bridged IdPs. See bug 910938.
    extra_params = {}
    if settings.UNVERIFIED_ISSUER:
        extra_params['experimental_forceIssuer'] = settings.UNVERIFIED_ISSUER

    if is_mobile:
        # When persona is running in a mobile OS then we can allow unverified
        # assertions.
        url = settings.NATIVE_BROWSERID_VERIFICATION_URL
        extra_params['experimental_allowUnverified'] = 'true'

    log.debug('Verifying Persona at %s, audience: %s, '
              'extra_params: %s' % (url, browserid_audience, extra_params))
    result = verify(assertion,
                    browserid_audience,
                    url=url,
                    extra_params=extra_params)
    if not result:
        return None, _('Persona authentication failure.')

    if 'unverified-email' in result:
        email = result['unverified-email']
        verified = False
    else:
        email = result['email']
        verified = True

    try:
        profile = UserProfile.objects.filter(email=email)[0]
    except IndexError:
        profile = None

    if profile:
        # Added due to bug 905984. It's possible to have a UserProfile
        # that has no corresponding User object.
        if profile.user is None:
            profile.create_django_user(
                backend='django_browserid.auth.BrowserIDBackend')
        if profile.is_verified and not verified:
            # An attempt to log in to a verified address with an unverified
            # assertion is a very bad thing. However, the same email address
            # can legitimately be used on the site on desktop and be verified
            # whilst be used on b2g and be unverified. We are forcing the
            # issuer, so this shouldn't be an issue.
            #
            # Blame kumar. Or cvan. Or deal with it.
            log.debug('Verified user %s attempted to log in with an '
                      'unverified assertion!' % profile)
        else:
            profile.is_verified = verified
            profile.save()

        backend = 'django_browserid.auth.BrowserIDBackend'
        if getattr(profile.user, 'backend', None) != backend:
            profile.user.backend = backend
            profile.user.save()

        return profile, None

    username = autocreate_username(email.partition('@')[0])
    source = (amo.LOGIN_SOURCE_MMO_BROWSERID
              if settings.MARKETPLACE else amo.LOGIN_SOURCE_AMO_BROWSERID)
    profile = UserProfile.objects.create(username=username,
                                         email=email,
                                         source=source,
                                         display_name=username,
                                         is_verified=verified)
    profile.create_django_user(
        backend='django_browserid.auth.BrowserIDBackend')
    log_cef('New Account',
            5,
            request,
            username=username,
            signature='AUTHNOTICE',
            msg='User created a new account (from Persona)')
    record_action('new-user', request)
    return profile, None
Esempio n. 42
0
def register(request):

    if settings.APP_PREVIEW and waffle.switch_is_active("browserid-login"):
        messages.error(request, loc("Registrations must be through browserid."))
        form = None
        raise http.Http404()

    elif request.user.is_authenticated():
        messages.info(request, _("You are already logged in to an account."))
        form = None

    elif request.method == "POST":

        form = forms.UserRegisterForm(request.POST)
        mkt_user = UserProfile.objects.filter(email=form.data["email"], password="")
        if form.is_valid():
            try:
                u = form.save(commit=False)
                u.set_password(form.cleaned_data["password"])
                u.generate_confirmationcode()
                u.save()
                u.create_django_user()
                log.info(u"Registered new account for user (%s)", u)
                log_cef(
                    "New Account",
                    5,
                    request,
                    username=u.username,
                    signature="AUTHNOTICE",
                    msg="User created a new account",
                )

                u.email_confirmation_code()

                msg = _("Congratulations! Your user account was " "successfully created.")
                messages.success(request, msg)

                msg = _(
                    u"An email has been sent to your address {0} to "
                    "confirm your account. Before you can log in, you "
                    "have to activate your account by clicking on the "
                    "link provided in this email."
                ).format(u.email)
                messages.info(request, _("Confirmation Email Sent"), msg)

            except IntegrityError, e:
                # I was unable to reproduce this, but I suspect it happens
                # when they POST twice quickly and the slaves don't have the
                # new info yet (total guess).  Anyway, I'm assuming the
                # first one worked properly, so this is still a success
                # case to the end user so we just log it...
                log.error("Failed to register new user (%s): %s" % (u, e))

            return http.HttpResponseRedirect(reverse("users.login"))

        elif mkt_user.exists():
            # Handle BrowserID
            if mkt_user.count() == 1 and mkt_user[0].source in amo.LOGIN_SOURCE_BROWSERIDS:
                messages.info(request, _("You already have an account."))
                form = None
            else:
                f = PasswordResetForm()
                f.users_cache = [mkt_user[0]]
                f.save(use_https=request.is_secure(), email_template_name="users/email/pwreset.ltxt", request=request)
                return jingo.render(request, "users/newpw_sent.html", {})
        else:
            messages.error(request, _("There are errors in this form"), _("Please correct them and resubmit."))
Esempio n. 43
0
def browserid_authenticate(request, assertion, is_mobile=False,
                           browserid_audience=get_audience):
    """
    Verify a BrowserID login attempt. If the BrowserID assertion is
    good, but no account exists, create one.

    """
    extra_params = {}
    if waffle.switch_is_active('firefox-accounts'):
        url = settings.NATIVE_FXA_VERIFICATION_URL
    else:
        url = settings.BROWSERID_VERIFICATION_URL

        # We must always force the Firefox OS identity provider. This is
        # because we are sometimes allowing unverified assertions and you
        # can't mix that feature with bridged IdPs. See bug 910938.

        if settings.UNVERIFIED_ISSUER:
            extra_params['experimental_forceIssuer'] = settings.UNVERIFIED_ISSUER

        if is_mobile:
            # When persona is running in a mobile OS then we can allow
            # unverified assertions.
            url = settings.NATIVE_BROWSERID_VERIFICATION_URL
            extra_params['experimental_allowUnverified'] = 'true'

    log.debug('Verifying Persona at %s, audience: %s, '
              'extra_params: %s' % (url, browserid_audience, extra_params))
    v = BrowserIDBackend().get_verifier()
    v.verification_service_url = url
    result = v.verify(assertion, browserid_audience, url=url, **extra_params)
    if not result:
        return None, _('Persona authentication failure.')

    if 'unverified-email' in result._response:
        email = result._response['unverified-email']
        verified = False
    elif (result._response.get('issuer') == settings.NATIVE_FXA_ISSUER and
          'fxa-verifiedEmail' in result._response.get('idpClaims', {})):
        email = result._response['idpClaims']['fxa-verifiedEmail']
        verified = True
    else:
        email = result.email
        verified = True

    try:
        profile = UserProfile.objects.filter(email=email)[0]
    except IndexError:
        profile = None

    if profile:
        if profile.is_verified and not verified:
            # An attempt to log in to a verified address with an unverified
            # assertion is a very bad thing. Don't let that happen.
            log.debug('Verified user %s attempted to log in with an '
                      'unverified assertion!' % profile)
            return None, _('Please use the verified email for this account.')
        else:
            profile.is_verified = verified
            profile.save()

        return profile, None

    username = autocreate_username(email.partition('@')[0])
    source = amo.LOGIN_SOURCE_MMO_BROWSERID
    profile = UserProfile.objects.create(username=username, email=email,
                                         source=source, display_name=username,
                                         is_verified=verified)
    log_cef('New Account', 5, request, username=username,
            signature='AUTHNOTICE',
            msg='User created a new account (from Persona)')
    record_action('new-user', request)

    return profile, None
Esempio n. 44
0
def browserid_authenticate(request, assertion, is_native=False,
                           browserid_audience=get_audience):
    """
    Verify a BrowserID login attempt. If the BrowserID assertion is
    good, but no account exists, create one.

    """
    url = settings.BROWSERID_VERIFICATION_URL

    # We must always force the Firefox OS identity provider. This is because
    # we are sometimes allowing unverified assertions and you can't mix that
    # feature with bridged IdPs. See bug 910938.
    extra_params = {}
    if settings.UNVERIFIED_ISSUER:
        extra_params['experimental_forceIssuer'] = settings.UNVERIFIED_ISSUER

    if is_native:
        # When persona is running native on B2G then we can allow unverified
        # assertions.
        url = settings.NATIVE_BROWSERID_VERIFICATION_URL
        extra_params['experimental_allowUnverified'] = 'true'

    log.debug('Verifying Persona at %s, audience: %s, '
              'extra_params: %s' % (url, browserid_audience, extra_params))
    result = verify(assertion, browserid_audience,
                    url=url, extra_params=extra_params)
    if not result:
        return None, _('Persona authentication failure.')

    if 'unverified-email' in result:
        email = result['unverified-email']
        verified = False
    else:
        email = result['email']
        verified = True

    try:
        profile = UserProfile.objects.filter(email=email)[0]
    except IndexError:
        profile = None

    if profile:
        # Added due to bug 905984. It's possible to have a UserProfile
        # that has no corresponding User object.
        if profile.user is None:
            profile.create_django_user(
                backend='django_browserid.auth.BrowserIDBackend')
        if profile.is_verified and not verified:
            # An attempt to log in to a verified address with an unverified
            # assertion is a very bad thing. However, the same email address
            # can legitimately be used on the site on desktop and be verified
            # whilst be used on b2g and be unverified. We are forcing the
            # issuer, so this shouldn't be an issue.
            #
            # Blame kumar. Or cvan. Or deal with it.
            log.debug('Verified user %s attempted to log in with an '
                      'unverified assertion!' % profile)
        else:
            profile.is_verified = verified
            profile.save()

        backend = 'django_browserid.auth.BrowserIDBackend'
        if getattr(profile.user, 'backend', None) != backend:
            profile.user.backend = backend
            profile.user.save()

        return profile, None

    username = autocreate_username(email.partition('@')[0])
    source = (amo.LOGIN_SOURCE_MMO_BROWSERID if settings.MARKETPLACE else
              amo.LOGIN_SOURCE_AMO_BROWSERID)
    profile = UserProfile.objects.create(username=username, email=email,
                                         source=source, display_name=username,
                                         is_verified=verified)
    profile.create_django_user(
        backend='django_browserid.auth.BrowserIDBackend')
    log_cef('New Account', 5, request, username=username,
            signature='AUTHNOTICE',
            msg='User created a new account (from Persona)')
    record_action('new-user', request)
    return profile, None
Esempio n. 45
0
    user_profile = UserProfile.objects.filter(email=buyer_email)

    if user_profile.exists():
        user_profile = user_profile.get()
    else:
        buyer_username = autocreate_username(buyer_email.partition('@')[0])
        source = amo.LOGIN_SOURCE_WEBPAY
        user_profile = UserProfile.objects.create(display_name=buyer_username,
                                                  email=buyer_email,
                                                  is_verified=True,
                                                  source=source,
                                                  username=buyer_username)

        log_cef('New Account',
                5,
                request,
                username=buyer_username,
                signature='AUTHNOTICE',
                msg='A new account was created from Webpay (using FxA)')
        record_action('new-user', request)

    log.info('webpay postback: fulfilling purchase for contrib %s with '
             'transaction %s' % (contrib, trans_id))
    app_pay_cef.log(request,
                    'Purchase complete',
                    'purchase_complete',
                    'Purchase complete for: %s' % (contrib.addon.pk),
                    severity=3)

    contrib.update(transaction_id=trans_id,
                   type=amo.CONTRIB_PURCHASE,
                   user=user_profile,
Esempio n. 46
0
def _login(request, template=None, data=None, dont_redirect=False):
    data = data or {}
    data['webapp'] = settings.APP_PREVIEW
    # In case we need it later.  See below.
    get_copy = request.GET.copy()

    if 'to' in request.GET:
        request = _clean_next_url(request)

    if request.user.is_authenticated():
        return http.HttpResponseRedirect(
            request.GET.get('to', settings.LOGIN_REDIRECT_URL))

    limited = getattr(request, 'limited', 'recaptcha_shown' in request.POST)
    user = None
    login_status = None
    if 'username' in request.POST:
        try:
            # We are doing all this before we try and validate the form.
            user = UserProfile.objects.get(email=request.POST['username'])
            limited = ((user.failed_login_attempts >=
                        settings.LOGIN_RATELIMIT_USER) or limited)
            login_status = False
        except UserProfile.DoesNotExist:
            log_cef('Authentication Failure', 5, request,
                    username=request.POST['username'],
                    signature='AUTHFAIL',
                    msg='The username was invalid')
            pass

    partial_form = partial(forms.AuthenticationForm, use_recaptcha=limited)
    r = auth.views.login(request, template_name=template,
                         redirect_field_name='to',
                         authentication_form=partial_form,
                         extra_context=data)

    if isinstance(r, http.HttpResponseRedirect):
        # Django's auth.views.login has security checks to prevent someone from
        # redirecting to another domain.  Since we want to allow this in
        # certain cases, we have to make a new response object here to replace
        # the above.

        if 'domain' in request.GET:
            request.GET = get_copy
            request = _clean_next_url(request)
            r = http.HttpResponseRedirect(request.GET['to'])

        # Succsesful log in according to django.  Now we do our checks.  I do
        # the checks here instead of the form's clean() because I want to use
        # the messages framework and it's not available in the request there.
        user = request.user.get_profile()

        if user.deleted:
            logout(request)
            log.warning(u'Attempt to log in with deleted account (%s)' % user)
            messages.error(request, _('Wrong email address or password!'))
            data.update({'form': partial_form()})
            user.log_login_attempt(False)
            log_cef('Authentication Failure', 5, request,
                    username=request.user,
                    signature='AUTHFAIL',
                    msg='Account is deactivated')
            return jingo.render(request, template, data)

        if user.confirmationcode:
            logout(request)
            log.info(u'Attempt to log in with unconfirmed account (%s)' % user)
            msg1 = _(u'A link to activate your user account was sent by email '
                      'to your address {0}. You have to click it before you '
                      'can log in.').format(user.email)
            url = "%s%s" % (settings.SITE_URL,
                            reverse('users.confirm.resend', args=[user.id]))
            msg2 = _('If you did not receive the confirmation email, make '
                      'sure your email service did not mark it as "junk '
                      'mail" or "spam". If you need to, you can have us '
                      '<a href="%s">resend the confirmation message</a> '
                      'to your email address mentioned above.') % url
            messages.error(request, _('Activation Email Sent'), msg1)
            messages.info(request, _('Having Trouble?'), msg2,
                          title_safe=True, message_safe=True)
            data.update({'form': partial_form()})
            user.log_login_attempt(False)
            return jingo.render(request, template, data)

        rememberme = request.POST.get('rememberme', None)
        if rememberme:
            request.session.set_expiry(settings.SESSION_COOKIE_AGE)
            log.debug((u'User (%s) logged in successfully with '
                                        '"remember me" set') % user)

        login_status = True

        if dont_redirect:
            # We're recalling the middleware to re-initialize amo_user
            ACLMiddleware().process_request(request)
            r = jingo.render(request, template, data)

    if login_status is not None:
        user.log_login_attempt(login_status)
        log_cef('Authentication Failure', 5, request,
                username=request.POST['username'],
                signature='AUTHFAIL',
                msg='The password was incorrect')

    return r
Esempio n. 47
0
def register(request):

    if settings.APP_PREVIEW:
        messages.error(request,
                       loc('Registrations must be through browserid.'))
        form = None

    elif (settings.REGISTER_USER_LIMIT
          and UserProfile.objects.count() > settings.REGISTER_USER_LIMIT
          and not can_override_reg_limit(request)):
        _m = loc('Sorry, no more registrations are allowed. '
                 '<a href="https://developer.mozilla.org/en-US/apps">'
                 'Learn more</a>')
        messages.error(request, _m, title_safe=True, message_safe=True)
        form = None

    elif request.user.is_authenticated():
        messages.info(request, _('You are already logged in to an account.'))
        form = None

    elif request.method == 'POST':

        form = forms.UserRegisterForm(request.POST)

        if form.is_valid():
            try:
                u = form.save(commit=False)
                u.set_password(form.cleaned_data['password'])
                u.generate_confirmationcode()
                u.save()
                u.create_django_user()
                log.info(u'Registered new account for user (%s)', u)
                log_cef('New Account',
                        5,
                        request,
                        username=u.username,
                        signature='AUTHNOTICE',
                        msg='User created a new account')

                u.email_confirmation_code()

                msg = _('Congratulations! Your user account was successfully '
                        'created.')
                messages.success(request, msg)

                msg = _(u'An email has been sent to your address {0} to '
                        'confirm your account. Before you can log in, you '
                        'have to activate your account by clicking on the '
                        'link provided in this email.').format(u.email)
                messages.info(request, _('Confirmation Email Sent'), msg)
            except IntegrityError, e:
                # I was unable to reproduce this, but I suspect it happens
                # when they POST twice quickly and the slaves don't have the
                # new info yet (total guess).  Anyway, I'm assuming the
                # first one worked properly, so this is still a success
                # case to tne end user so we just log it...
                log.error('Failed to register new user (%s): %s' % (u, e))

            return http.HttpResponseRedirect(reverse('users.login'))

        else:
            messages.error(request, _('There are errors in this form'),
                           _('Please correct them and resubmit.'))
Esempio n. 48
0
def paypal_log_cef(request, addon, uuid, msg, caps, longer):
    log_cef('Paypal %s' % msg, 5, request,
            username=request.amo_user,
            signature='PAYPAL%s' % caps,
            msg=longer, cs2=addon.name, cs2Label='PaypalTransaction',
            cs4=uuid, cs4Label='TxID')
Esempio n. 49
0
def browserid_authenticate(request,
                           assertion,
                           is_native=False,
                           browserid_audience=get_audience):
    """
    Verify a BrowserID login attempt. If the BrowserID assertion is
    good, but no account exists, create one.

    """
    url = settings.BROWSERID_VERIFICATION_URL
    extra_params = None
    if is_native:
        # When persona is running native on B2G then we need to
        # verify assertions with the right service.
        # We also need to force the appropriate issuer
        # for potentially unverified emails.
        url = settings.NATIVE_BROWSERID_VERIFICATION_URL
        extra_params = {
            'experimental_forceIssuer': settings.UNVERIFIED_ISSUER or False,
            'experimental_allowUnverified': 'true'
        }

    log.debug('Verifying Persona at %s, audience: %s, '
              'extra_params: %s' % (url, browserid_audience, extra_params))
    result = verify(assertion,
                    browserid_audience,
                    url=url,
                    extra_params=extra_params)
    if not result:
        return None, _('Persona authentication failure.')

    if 'unverified-email' in result:
        email = result['unverified-email']
        verified = False
    else:
        email = result['email']
        verified = True

    try:
        profile = UserProfile.objects.filter(email=email)[0]
    except IndexError:
        profile = None

    if profile:
        if profile.is_verified and not verified:
            # An attempt to log in to a verified address with an unverified
            # assertion is a very bad thing. However, the same email address
            # can legitimately be used on the site on desktop and be verified
            # whilst be used on b2g and be unverified. We are forcing the
            # issuer, so this shouldn't be an issue.
            #
            # Blame kumar. Or cvan. Or deal with it.
            log.debug('Verified user %s attempted to log in with an '
                      'unverified assertion!' % profile)
        else:
            profile.is_verified = verified
            profile.save()

        backend = 'django_browserid.auth.BrowserIDBackend'
        if getattr(profile.user, 'backend', None) != backend:
            profile.user.backend = backend
            profile.user.save()

        return profile, None

    username = autocreate_username(email.partition('@')[0])
    source = (amo.LOGIN_SOURCE_MMO_BROWSERID
              if settings.MARKETPLACE else amo.LOGIN_SOURCE_AMO_BROWSERID)
    profile = UserProfile.objects.create(username=username,
                                         email=email,
                                         source=source,
                                         display_name=username,
                                         is_verified=verified)
    profile.create_django_user(
        backend='django_browserid.auth.BrowserIDBackend')
    log_cef('New Account',
            5,
            request,
            username=username,
            signature='AUTHNOTICE',
            msg='User created a new account (from Persona)')
    record_action('new-user', request)
    return profile, None