def emailchange(request, user, token, hash): try: _uid, newemail = EmailResetCode.parse(token, hash) except ValueError: return http.HttpResponse(status=400) if _uid != user.id: # I'm calling this a warning because invalid hashes up to this point # could be any number of things, but this is a targeted attack from # one user account to another log.warning((u"[Tampering] Valid email reset code for UID (%s) " u"attempted to change email address for user (%s)") % (_uid, user)) return http.HttpResponse(status=400) if UserProfile.objects.filter(email=newemail).exists(): log.warning((u"[Tampering] User (%s) tries to change his email to " u"an existing account with the same email address (%s)") % (user, newemail)) return http.HttpResponse(status=400) user.email = newemail user.save() l = {'user': user, 'newemail': newemail} log.info(u"User (%(user)s) confirmed new email address (%(newemail)s)" % l) messages.success( request, _('Your email address was changed successfully'), _(u'From now on, please use {0} to log in.').format(newemail)) return http.HttpResponseRedirect(reverse('users.edit'))
def features(request): form = FeaturedCollectionFormSet(request.POST or None) if request.method == 'POST' and form.is_valid(): form.save(commit=False) messages.success(request, 'Changes successfully saved.') return redirect('zadmin.features') return render(request, 'zadmin/features.html', dict(form=form))
def monthly_pick(request): form = MonthlyPickFormSet(request.POST or None) if request.method == 'POST' and form.is_valid(): form.save() messages.success(request, 'Changes successfully saved.') return redirect('zadmin.monthly_pick') return render(request, 'zadmin/monthly_pick.html', dict(form=form))
def hera(request): form = FlushForm(initial={'flushprefix': settings.SITE_URL}) boxes = [] configured = False # Default to not showing the form. for i in settings.HERA: hera = get_hera(i) r = {'location': urlparse(i['LOCATION'])[1], 'stats': False} if hera: r['stats'] = hera.getGlobalCacheInfo() configured = True boxes.append(r) if not configured: messages.error(request, "Hera is not (or mis-)configured.") form = None if request.method == 'POST' and hera: form = FlushForm(request.POST) if form.is_valid(): expressions = request.POST['flushlist'].splitlines() for url in expressions: num = flush_urls([url], request.POST['flushprefix'], True) msg = ("Flushed %d objects from front end cache for: %s" % (len(num), url)) log.info("[Hera] (user:%s) %s" % (request.user, msg)) messages.success(request, msg) return render(request, 'zadmin/hera.html', {'form': form, 'boxes': boxes})
def login_user(request, user, identity): migrated = update_user(user, identity) if migrated: messages.success( request, _(u"Great job!"), _(u"You can now log in to Add-ons with your Firefox Account."), extra_tags="fxa" ) log.info("Logging in user {} from FxA".format(user)) login(request, user)
def report_abuse(request, user): form = AbuseForm(request.POST or None, request=request) if request.method == "POST" and form.is_valid(): send_abuse_report(request, user, form.cleaned_data["text"]) messages.success(request, _("User reported.")) else: return render(request, "users/report_abuse_full.html", {"profile": user, "abuse_form": form}) return redirect(user.get_url_path())
def report_abuse(request, addon): form = AbuseForm(request.POST or None, request=request) if request.method == "POST" and form.is_valid(): send_abuse_report(request, addon, form.cleaned_data['text']) messages.success(request, _('Abuse reported.')) return http.HttpResponseRedirect(addon.get_url_path()) else: return render(request, 'addons/report_abuse_full.html', {'addon': addon, 'abuse_form': form})
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 report_abuse(request, user): form = AbuseForm(request.POST or None, request=request) if request.method == 'POST' and form.is_valid(): send_abuse_report(request, user, form.cleaned_data['text']) messages.success(request, ugettext('User reported.')) else: return render(request, 'users/report_abuse_full.html', {'profile': user, 'abuse_form': form}) return redirect(user.get_url_path())
def admin_edit(request, user): if request.method == "POST": form = forms.AdminUserEditForm(request.POST, request.FILES, request=request, instance=user) if form.is_valid(): form.save() messages.success(request, _("Profile Updated")) return http.HttpResponseRedirect(reverse("zadmin.index")) else: form = forms.AdminUserEditForm(instance=user, request=request) return render(request, "users/edit.html", {"form": form, "amouser": user})
def login_user(request, user, identity): migrated = update_user(user, identity) if migrated: messages.success( request, _(u'Great job!'), _(u'You can now log in to Add-ons with your Firefox Account.'), extra_tags='fxa') log.info('Logging in user {} from FxA'.format(user)) login(request, user)
def fix_disabled_file(request): file_ = None if request.method == 'POST' and 'file' in request.POST: file_ = get_object_or_404(File, id=request.POST['file']) if 'confirm' in request.POST: file_.unhide_disabled_file() messages.success(request, 'We have done a great thing.') return redirect('zadmin.fix-disabled') return render(request, 'zadmin/fix-disabled.html', {'file': file_, 'file_id': request.POST.get('file', '')})
def edit(request): # Don't use request.user since it has too much caching. amouser = UserProfile.objects.get(pk=request.user.id) if request.method == 'POST': # ModelForm alters the instance you pass in. We need to keep a copy # around in case we need to use it below (to email the user) original_email = amouser.email form = forms.UserEditForm(request.POST, request.FILES, request=request, instance=amouser) if form.is_valid(): messages.success(request, _('Profile Updated')) if amouser.email != original_email: l = {'user': amouser, 'mail1': original_email, 'mail2': amouser.email} log.info(u"User (%(user)s) has requested email change from " u"(%(mail1)s) to (%(mail2)s)" % l) messages.info( request, _('Email Confirmation Sent'), _(u'An email has been sent to {0} to confirm your new ' u'email address. For the change to take effect, you ' u'need to click on the link provided in this email. ' u'Until then, you can keep logging in with your ' u'current email address.').format(amouser.email)) token, hash_ = EmailResetCode.create(amouser.id, amouser.email) url = '%s%s' % (settings.SITE_URL, reverse('users.emailchange', args=[amouser.id, token, hash_])) t = loader.get_template('users/email/emailchange.ltxt') c = {'domain': settings.DOMAIN, 'url': url} send_mail( _('Please confirm your email address ' 'change at %s' % settings.DOMAIN), t.render(Context(c)), None, [amouser.email], use_blacklist=False, real_email=True) # Reset the original email back. We aren't changing their # address until they confirm the new one amouser.email = original_email form.save() return redirect('users.edit') else: messages.error( request, _('Errors Found'), _('There were errors in the changes you made. Please correct ' 'them and resubmit.')) else: form = forms.UserEditForm(instance=amouser, request=request) return render(request, 'users/edit.html', {'form': form, 'amouser': amouser})
def admin_edit(request, user): if request.method == 'POST': form = forms.AdminUserEditForm(request.POST, request.FILES, request=request, instance=user) if form.is_valid(): form.save() messages.success(request, ugettext('Profile Updated')) return http.HttpResponseRedirect(reverse('zadmin.index')) else: form = forms.AdminUserEditForm(instance=user, request=request) return render(request, 'users/edit.html', {'form': form, 'amouser': user})
def recalc_hash(request, file_id): file = get_object_or_404(File, pk=file_id) file.size = storage.size(file.file_path) file.hash = file.generate_hash() file.save() log.info('Recalculated hash for file ID %d' % file.id) messages.success(request, 'File hash and size recalculated for file %d.' % file.id) return {'success': 1}
def login_user(request, user, identity): migrated = update_user(user, identity) if migrated and not switch_is_active('fxa-migrated'): messages.success( request, _(u'Great job!'), _(u'You can now log in to Add-ons with your Firefox Account.'), extra_tags='fxa') log.info('Logging in user {} from FxA'.format(user)) user.log_login_attempt(True) login(request, user)
def memcache(request): form = YesImSure(request.POST or None) if form.is_valid() and form.cleaned_data['yes']: cache.clear() form = YesImSure() messages.success(request, 'Cache cleared') if cache._cache and hasattr(cache._cache, 'get_stats'): stats = cache._cache.get_stats() else: stats = [] return render(request, 'zadmin/memcache.html', {'form': form, 'stats': stats})
def delete_icon(request, collection, username, slug): log.debug(u"User deleted collection (%s) icon " % slug) tasks.delete_icon(os.path.join(collection.get_img_dir(), '%d.png' % collection.id)) collection.icontype = '' collection.save() if request.is_ajax(): return {'icon': collection.icon_url} else: messages.success(request, _('Icon Deleted')) return http.HttpResponseRedirect(collection.edit_url())
def delete_photo(request): u = request.user if request.method == 'POST': u.picture_type = '' u.save() log.debug(u"User (%s) deleted photo" % u) tasks.delete_photo.delay(u.picture_path) messages.success(request, _('Photo Deleted')) return http.HttpResponseRedirect(reverse('users.edit') + '#user-profile') return render(request, 'users/delete_photo.html', dict(user=u))
def confirm(request, user, token): if not user.confirmationcode: return redirect('users.login') if user.confirmationcode != token: log.info(u"Account confirmation failed for user (%s)", user) messages.error(request, _('Invalid confirmation code!')) return redirect('users.login') user.confirmationcode = '' user.save() messages.success(request, _('Successfully verified!')) log.info(u"Account confirmed for user (%s)", user) return redirect('users.login')
def delete(request): amouser = request.user if request.method == "POST": form = forms.UserDeleteForm(request.POST, request=request) if form.is_valid(): messages.success(request, _("Profile Deleted")) amouser.anonymize() logout(request) form = None return http.HttpResponseRedirect(reverse("home")) else: form = forms.UserDeleteForm(request=request) return render(request, "users/delete.html", {"form": form, "amouser": amouser})
def memcache(request): form = YesImSure(request.POST or None) if form.is_valid() and form.cleaned_data['yes']: cache.clear() form = YesImSure() messages.success(request, 'Cache cleared') if cache._cache and hasattr(cache._cache, 'get_stats'): stats = cache._cache.get_stats() else: stats = [] return render(request, 'zadmin/memcache.html', { 'form': form, 'stats': stats })
def collection_message(request, collection, option): if option == 'add': title = _('Collection created!') msg = _("""Your new collection is shown below. You can <a href="%(url)s">edit additional settings</a> if you'd like.""") % {'url': collection.edit_url()} elif option == 'update': title = _('Collection updated!') msg = _("""<a href="%(url)s">View your collection</a> to see the changes.""") % {'url': collection.get_url_path()} else: raise ValueError('Incorrect option "%s", ' 'takes only "add" or "update".' % option) messages.success(request, title, msg, message_safe=True)
def email_devs(request): form = DevMailerForm(request.POST or None) preview = EmailPreviewTopic(topic='email-devs') if preview.filter().count(): preview_csv = reverse('zadmin.email_preview_csv', args=[preview.topic]) else: preview_csv = None if request.method == 'POST' and form.is_valid(): data = form.cleaned_data qs = (AddonUser.objects.filter(role__in=(amo.AUTHOR_ROLE_DEV, amo.AUTHOR_ROLE_OWNER)) .exclude(user__email=None) .filter(addon__status__in=amo.LISTED_STATUSES)) if data['recipients'] == 'eula': qs = qs.exclude(addon__eula=None) elif data['recipients'] == 'sdk': qs = qs.exclude(addon__versions__files__jetpack_version=None) elif data['recipients'] == 'all_extensions': qs = qs.filter(addon__type=amo.ADDON_EXTENSION) elif data['recipients'] == 'fxa': # We're limiting to logins since 2014 to limit the list # dramatically. There was an import from getpersonas.com in 2013 # and if you haven't logged in within the last two years you # likely won't migrate. qs = qs.filter( Q(user__fxa_id__isnull=True) | Q(user__fxa_id=''), user__last_login__gte=datetime(year=2014, month=1, day=1)) else: raise NotImplementedError('If you want to support emailing other ' 'types of developers, do it here!') if data['preview_only']: # Clear out the last batch of previewed emails. preview.filter().delete() total = 0 for emails in chunked(set(qs.values_list('user__email', flat=True)), 100): total += len(emails) tasks.admin_email.delay(emails, data['subject'], data['message'], preview_only=data['preview_only'], preview_topic=preview.topic) msg = 'Emails queued for delivery: %s' % total if data['preview_only']: msg = '%s (for preview only, emails not sent!)' % msg messages.success(request, msg) return redirect('zadmin.email_devs') return render(request, 'zadmin/email-devs.html', dict(form=form, preview_csv=preview_csv))
def delete(request): amouser = request.user if request.method == 'POST': form = forms.UserDeleteForm(request.POST, request=request) if form.is_valid(): messages.success(request, ugettext('Profile Deleted')) amouser.delete() response = http.HttpResponseRedirect(reverse('home')) logout_user(request, response) return response else: form = forms.UserDeleteForm(request=request) return render(request, 'users/delete.html', {'form': form, 'amouser': amouser})
def delete(request): amouser = request.user if request.method == 'POST': form = forms.UserDeleteForm(request.POST, request=request) if form.is_valid(): messages.success(request, _('Profile Deleted')) amouser.anonymize() logout(request) form = None return http.HttpResponseRedirect(reverse('users.login')) else: form = forms.UserDeleteForm(request=request) return render(request, 'users/delete.html', {'form': form, 'amouser': amouser})
def email_devs(request): form = DevMailerForm(request.POST or None) preview = EmailPreviewTopic(topic='email-devs') if preview.filter().count(): preview_csv = reverse('zadmin.email_preview_csv', args=[preview.topic]) else: preview_csv = None if request.method == 'POST' and form.is_valid(): data = form.cleaned_data qs = ( AddonUser.objects.filter( role__in=(amo.AUTHOR_ROLE_DEV, amo.AUTHOR_ROLE_OWNER)) .exclude(user__email=None) .filter(addon__status__in=amo.VALID_ADDON_STATUSES)) if data['recipients'] == 'eula': qs = qs.exclude(addon__eula=None) elif data['recipients'] == 'sdk': qs = qs.exclude(addon__versions__files__jetpack_version=None) elif data['recipients'] == 'all_extensions': qs = qs.filter(addon__type=amo.ADDON_EXTENSION) elif data['recipients'] == 'depreliminary': addon_logs = AddonLog.objects.filter( activity_log__action=amo.LOG.PRELIMINARY_ADDON_MIGRATED.id, activity_log___details__contains='"email": true') addons = addon_logs.values_list('addon', flat=True) qs = qs.filter(addon__in=addons) else: raise NotImplementedError('If you want to support emailing other ' 'types of developers, do it here!') if data['preview_only']: # Clear out the last batch of previewed emails. preview.filter().delete() total = 0 for emails in chunked(set(qs.values_list('user__email', flat=True)), 100): total += len(emails) tasks.admin_email.delay(emails, data['subject'], data['message'], preview_only=data['preview_only'], preview_topic=preview.topic) msg = 'Emails queued for delivery: %s' % total if data['preview_only']: msg = '%s (for preview only, emails not sent!)' % msg messages.success(request, msg) return redirect('zadmin.email_devs') return render(request, 'zadmin/email-devs.html', dict(form=form, preview_csv=preview_csv))
def delete(request): amouser = request.user if request.method == 'POST': form = forms.UserDeleteForm(request.POST, request=request) if form.is_valid(): messages.success(request, _('Profile Deleted')) amouser.anonymize() logout(request) form = None return http.HttpResponseRedirect(reverse('users.login')) else: form = forms.UserDeleteForm(request=request) return render(request, 'users/delete.html', { 'form': form, 'amouser': amouser })
def delete_photo(request, user_id): not_mine = str(request.user.id) != user_id if not_mine and not acl.action_allowed(request, "Users", "Edit"): return http.HttpResponseForbidden() user = UserProfile.objects.get(id=user_id) if request.method == "POST": user.picture_type = "" user.save() log.debug(u"User (%s) deleted photo" % user) tasks.delete_photo.delay(user.picture_path) messages.success(request, _("Photo Deleted")) redirect = reverse("users.admin_edit", kwargs={"user_id": user.id}) if not_mine else reverse("users.edit") return http.HttpResponseRedirect(redirect + "#user-profile") return render(request, "users/delete_photo.html", dict(user=user))
def collection_message(request, collection, option): if option == 'add': title = ugettext('Collection created!') msg = ugettext( 'Your new collection is shown below. You can ' '<a href="%(url)s">edit additional settings</a> if you\'d ' 'like.' ) % {'url': collection.edit_url()} elif option == 'update': title = ugettext('Collection updated!') msg = ugettext( '<a href="%(url)s">View your collection</a> to see the changes.' ) % {'url': collection.get_url_path()} else: raise ValueError('Incorrect option "%s", ' 'takes only "add" or "update".' % option) messages.success(request, title, msg, message_safe=True)
def login_user(request, user, identity): if (user.fxa_id != identity['uid'] or user.email != identity['email']): log.info( 'Updating user info from FxA for {pk}. Old {old_email} {old_uid} ' 'New {new_email} {new_uid}'.format( pk=user.pk, old_email=user.email, old_uid=user.fxa_id, new_email=identity['email'], new_uid=identity['uid'])) if not user.fxa_migrated(): messages.success( request, _(u'Great job!'), _(u'You can now log in to Add-ons with your Firefox Account.'), extra_tags='fxa') user.update(fxa_id=identity['uid'], email=identity['email']) log.info('Logging in user {} from FxA'.format(user)) login(request, user)
def delete_photo(request, user_id): not_mine = str(request.user.id) != user_id if (not_mine and not acl.action_allowed(request, 'Users', 'Edit')): return http.HttpResponseForbidden() user = UserProfile.objects.get(id=user_id) if request.method == 'POST': user.picture_type = '' user.save() log.debug(u'User (%s) deleted photo' % user) tasks.delete_photo.delay(user.picture_path) messages.success(request, _('Photo Deleted')) redirect = (reverse('users.admin_edit', kwargs={'user_id': user.id}) if not_mine else reverse('users.edit')) return http.HttpResponseRedirect(redirect + '#user-profile') return render(request, 'users/delete_photo.html', dict(user=user))
def delete_photo(request, user_id): not_mine = str(request.user.id) != user_id if (not_mine and not acl.action_allowed(request, 'Users', 'Edit')): return http.HttpResponseForbidden() user = UserProfile.objects.get(id=user_id) if request.method == 'POST': user.picture_type = '' user.save() log.debug(u'User (%s) deleted photo' % user) tasks.delete_photo.delay(user.picture_path) messages.success(request, _('Photo Deleted')) redirect = ( reverse('users.admin_edit', kwargs={'user_id': user.id}) if not_mine else reverse('users.edit') ) return http.HttpResponseRedirect(redirect + '#user-profile') return render(request, 'users/delete_photo.html', dict(user=user))
def edit(request): # Don't use request.user since it has too much caching. amouser = UserProfile.objects.get(pk=request.user.id) if request.method == "POST": # ModelForm alters the instance you pass in. We need to keep a copy # around in case we need to use it below (to email the user) form = forms.UserEditForm(request.POST, request.FILES, request=request, instance=amouser) if form.is_valid(): messages.success(request, _("Profile Updated")) form.save() return redirect("users.edit") else: messages.error( request, _("Errors Found"), _("There were errors in the changes you made. Please correct " "them and resubmit."), ) else: form = forms.UserEditForm(instance=amouser, request=request) return render(request, "users/edit.html", {"form": form, "amouser": amouser})
def edit(request): # Don't use request.user since it has too much caching. amouser = UserProfile.objects.get(pk=request.user.id) if request.method == 'POST': # ModelForm alters the instance you pass in. We need to keep a copy # around in case we need to use it below (to email the user) form = forms.UserEditForm(request.POST, request.FILES, request=request, instance=amouser) if form.is_valid(): messages.success(request, ugettext('Profile Updated')) form.save() return redirect('users.edit') else: messages.error( request, ugettext('Errors Found'), ugettext('There were errors in the changes you made. ' 'Please correct them and resubmit.')) else: form = forms.UserEditForm(instance=amouser, request=request) return render(request, 'users/edit.html', {'form': form, 'amouser': amouser})
def spam(request): if not acl.action_allowed(request, 'Spam', 'Flag'): raise PermissionDenied spam = Spam() if request.method == 'POST': review = Review.objects.get(pk=request.POST['review']) if 'del_review' in request.POST: log.info('SPAM: %s' % review.id) delete(request, request.POST['addon'], review.id) messages.success(request, 'Deleted that review.') elif 'del_user' in request.POST: user = review.user log.info('SPAMMER: %s deleted %s' % (request.user.username, user.username)) if not user.is_developer: Review.objects.filter(user=user).delete() user.anonymize() messages.success(request, 'Deleted that dirty spammer.') for reason in spam.reasons(): spam.redis.srem(reason, review.id) return http.HttpResponseRedirect(request.path) buckets = {} for reason in spam.reasons(): ids = spam.redis.smembers(reason) key = reason.split(':')[-1] buckets[key] = Review.objects.no_cache().filter(id__in=ids) reviews = dict((review.addon_id, review) for bucket in buckets.values() for review in bucket) for addon in Addon.objects.no_cache().filter(id__in=reviews): reviews[addon.id].addon = addon return render(request, 'reviews/spam.html', dict(buckets=buckets, review_perms=dict(is_admin=True)))