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
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.'))
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))
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()
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)
def paypal_log_cef(request, addon, uuid, msg, caps, longer): log_cef('Paypal %s' % msg, 5, request, username=request.user, signature='PAYPAL%s' % caps, msg=longer, cs2=addon.name, cs2Label='PaypalTransaction', cs4=uuid, cs4Label='TxID')
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 olympia.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)
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 user.fxa_migrated() and waffle.switch_is_active('fxa-auth')): migrated = True validlink = False form = None elif user is not None and default_token_generator.check_token(user, token): migrated = False 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: migrated = False validlink = False form = None return render(request, 'users/pwreset_confirm.html', { 'form': form, 'validlink': validlink, 'migrated': migrated })
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.user.username, cs1Label='AdminName') return profile
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 user.fxa_migrated() and waffle.switch_is_active('fxa-auth')): migrated = True validlink = False form = None elif user is not None and default_token_generator.check_token(user, token): migrated = False 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: migrated = False validlink = False form = None return render(request, 'users/pwreset_confirm.html', {'form': form, 'validlink': validlink, 'migrated': migrated})
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
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)) data['login_source_form'] = (waffle.switch_is_active('fxa-auth') and not request.POST) 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. request.GET = get_copy request = _clean_next_url(request) next_path = request.GET['to'] if waffle.switch_is_active('fxa-auth'): if next_path == '/': next_path = None next_path = urlparams(reverse('users.migrate'), to=next_path) r = http.HttpResponseRedirect(next_path) # 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 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
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)) data['login_source_form'] = (waffle.switch_is_active('fxa-auth') and not request.POST) 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. request.GET = get_copy request = _clean_next_url(request) next_path = request.GET['to'] if waffle.switch_is_active('fxa-auth'): if next_path == '/': next_path = None next_path = urlparams(reverse('users.migrate'), to=next_path) r = http.HttpResponseRedirect(next_path) # 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 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