def send(self): obj = self.object if self.reporter: user_name = '%s (%s)' % (self.reporter.name, self.reporter.email) else: user_name = 'An anonymous user' if self.website: # For Websites, it's not just abuse, the scope is broader, it could # be any issue about the website listing itself, so use a different # wording and recipient list. type_ = u'Website' subject = u'[%s] Issue Report for %s' % (type_, obj.name) recipient_list = (settings.MKT_FEEDBACK_EMAIL, ) else: if self.addon: type_ = 'App' elif self.user: type_ = 'User' subject = u'[%s] Abuse Report for %s' % (type_, obj.name) recipient_list = (settings.ABUSE_EMAIL, ) msg = u'%s reported an issue for %s (%s%s).\n\n%s' % ( user_name, obj.name, settings.SITE_URL, obj.get_url_path(), self.message) send_mail(subject, msg, recipient_list=recipient_list)
def send(self): obj = self.object if self.reporter: user_name = '%s (%s)' % (self.reporter.name, self.reporter.email) else: user_name = 'An anonymous coward' if self.website: # For Websites, it's not just abuse, the scope is broader, it could # be any issue about the website listing itself, so use a different # wording and recipient list. type_ = u'Website' subject = u'[%s] Issue Report for %s' % (type_, obj.name) recipient_list = (settings.MKT_FEEDBACK_EMAIL,) else: if self.addon: type_ = 'App' elif self.user: type_ = 'User' subject = u'[%s] Abuse Report for %s' % (type_, obj.name) recipient_list = (settings.ABUSE_EMAIL,) msg = u'%s reported an issue for %s (%s%s).\n\n%s' % ( user_name, obj.name, settings.SITE_URL, obj.get_url_path(), self.message) send_mail(subject, msg, recipient_list=recipient_list)
def _mail(self, template, subject, context): template = env.get_template(template) body = template.render(context) send_mail(subject, body, settings.MARKETPLACE_EMAIL, [self.user.email], fail_silently=True)
def test_async_will_stop_retrying(self, backend): backend.side_effect = self.make_backend_class([True, True]) with self.assertRaises(RuntimeError): send_mail('test subject', 'test body', async=True, max_retries=1, recipient_list=['*****@*****.**'])
def test_async_will_retry(self, backend): backend.side_effect = self.make_backend_class([True, True, False]) with self.assertRaises(RuntimeError): send_mail('test subject', 'test body', recipient_list=['*****@*****.**']) assert send_mail('test subject', 'test body', async=True, recipient_list=['*****@*****.**'])
def send(self): obj = self.addon or self.user if self.reporter: user_name = '%s (%s)' % (self.reporter.name, self.reporter.email) else: user_name = 'An anonymous coward' type_ = ('App' if self.addon else 'User') subject = u'[%s] Abuse Report for %s' % (type_, obj.name) msg = u'%s reported abuse for %s (%s%s).\n\n%s' % ( user_name, obj.name, settings.SITE_URL, obj.get_url_path(), self.message) send_mail(subject, msg, recipient_list=(settings.ABUSE_EMAIL, ))
def send(self): obj = self.addon or self.user if self.reporter: user_name = '%s (%s)' % (self.reporter.name, self.reporter.email) else: user_name = 'An anonymous coward' type_ = ('App' if self.addon else 'User') subject = u'[%s] Abuse Report for %s' % (type_, obj.name) msg = u'%s reported abuse for %s (%s%s).\n\n%s' % ( user_name, obj.name, settings.SITE_URL, obj.get_url_path(), self.message) send_mail(subject, msg, recipient_list=(settings.ABUSE_EMAIL,))
def test_success_fake_mail(self): assert send_mail('test subject', 'test body', recipient_list=['*****@*****.**'], fail_silently=False) eq_(len(mail.outbox), 0) eq_(FakeEmail.objects.count(), 1) eq_(FakeEmail.objects.get().message.endswith('test body'), True)
def test_success_real_mail(self): assert send_mail('test subject', 'test body', recipient_list=['*****@*****.**'], fail_silently=False) eq_(len(mail.outbox), 1) eq_(mail.outbox[0].subject.find('test subject'), 0) eq_(mail.outbox[0].body.find('test body'), 0)
def test_blacklist(self): to = "*****@*****.**" to2 = "*****@*****.**" settings.EMAIL_BLACKLIST = (to,) success = send_mail("test subject", "test body", recipient_list=[to, to2], fail_silently=False) assert success eq_(len(mail.outbox), 1) eq_(mail.outbox[0].to, [to2])
def test_blocked(self): to = '*****@*****.**' to2 = '*****@*****.**' settings.EMAIL_BLOCKED = (to,) success = send_mail('test subject', 'test body', recipient_list=[to, to2], fail_silently=False) assert success eq_(len(mail.outbox), 1) eq_(mail.outbox[0].to, [to2])
def test_blacklist(self): to = '*****@*****.**' to2 = '*****@*****.**' settings.EMAIL_BLACKLIST = (to,) success = send_mail('test subject', 'test body', recipient_list=[to, to2], fail_silently=False) assert success eq_(len(mail.outbox), 1) eq_(mail.outbox[0].to, [to2])
def test_blocked_flag(self): to = '*****@*****.**' to2 = '*****@*****.**' settings.EMAIL_BLOCKED = (to,) success = send_mail('test subject', 'test body', recipient_list=[to, to2], fail_silently=False, use_blocked=True) assert success eq_(len(mail.outbox), 1) eq_(mail.outbox[0].to, [to2])
def test_blacklist_flag(self): to = '*****@*****.**' to2 = '*****@*****.**' settings.EMAIL_BLACKLIST = (to,) success = send_mail('test subject', 'test body', recipient_list=[to, to2], fail_silently=False, use_blacklist=True) assert success eq_(len(mail.outbox), 1) eq_(mail.outbox[0].to, [to2])
def test_user_setting_checked(self): user = UserProfile.objects.all()[0] to = user.email n = mkt.users.notifications.NOTIFICATIONS_BY_SHORT["reply"] UserNotification.objects.get_or_create(notification_id=n.id, user=user, enabled=True) # Confirm we're reading from the database eq_(UserNotification.objects.filter(notification_id=n.id).count(), 1) success = send_mail("test subject", "test body", perm_setting="reply", recipient_list=[to], fail_silently=False) assert success, "Email wasn't sent" eq_(len(mail.outbox), 1)
def test_user_mandatory(self): user = UserProfile.objects.all()[0] to = user.email n = mkt.users.notifications.NOTIFICATIONS_BY_SHORT["individual_contact"] UserNotification.objects.get_or_create(notification_id=n.id, user=user, enabled=True) assert n.mandatory, "Notification isn't mandatory" success = send_mail("test subject", "test body", perm_setting=n, recipient_list=[to], fail_silently=False) assert success, "Email wasn't sent" eq_(len(mail.outbox), 1)
def test_real_list(self): to = "*****@*****.**" to2 = "*****@*****.**" to3 = "*****@*****.**" set_config("real_email_whitelist", to3) success = send_mail("test subject", "test_real_list", recipient_list=[to, to2, to3], fail_silently=False) assert success eq_(len(mail.outbox), 1) eq_(mail.outbox[0].to, [to3]) assert "test_real_list" in mail.outbox[0].body eq_(FakeEmail.objects.count(), 1) # Only one mail, two recipients. fakeemail = FakeEmail.objects.get() eq_(fakeemail.message.endswith("test_real_list"), True) assert ("To: %s, %s" % (to, to2)) in fakeemail.message
def test_user_mandatory(self): user = UserProfile.objects.all()[0] to = user.email n = mkt.users.notifications.NOTIFICATIONS_BY_SHORT['individual_contact'] UserNotification.objects.get_or_create(notification_id=n.id, user=user, enabled=True) assert n.mandatory, "Notification isn't mandatory" success = send_mail('test subject', 'test body', perm_setting=n, recipient_list=[to], fail_silently=False) assert success, "Email wasn't sent" eq_(len(mail.outbox), 1)
def test_user_setting_default(self): user = UserProfile.objects.all()[0] to = user.email # Confirm there's nothing in the DB and we're using the default eq_(UserNotification.objects.count(), 0) # Make sure that this is True by default setting = mkt.users.notifications.NOTIFICATIONS_BY_SHORT["reply"] eq_(setting.default_checked, True) success = send_mail("test subject", "test body", perm_setting="reply", recipient_list=[to], fail_silently=False) assert success, "Email wasn't sent" eq_(len(mail.outbox), 1)
def test_real_list(self): to = '*****@*****.**' to2 = '*****@*****.**' to3 = '*****@*****.**' set_config('real_email_whitelist', to3) success = send_mail('test subject', 'test_real_list', recipient_list=[to, to2, to3], fail_silently=False) assert success eq_(len(mail.outbox), 1) eq_(mail.outbox[0].to, [to3]) assert 'test_real_list' in mail.outbox[0].body eq_(FakeEmail.objects.count(), 1) # Only one mail, two recipients. fakeemail = FakeEmail.objects.get() eq_(fakeemail.message.endswith('test_real_list'), True) assert ('To: %s, %s' % (to, to2)) in fakeemail.message
def test_user_setting_unchecked(self): user = UserProfile.objects.all()[0] to = user.email n = mkt.users.notifications.NOTIFICATIONS_BY_SHORT['reply'] UserNotification.objects.get_or_create(notification_id=n.id, user=user, enabled=False) # Confirm we're reading from the database. eq_(UserNotification.objects.filter(notification_id=n.id).count(), 1) success = send_mail('test subject', 'test body', perm_setting='reply', recipient_list=[to], fail_silently=False) assert success, "Email wasn't sent" eq_(len(mail.outbox), 0)
def test_user_setting_default(self): user = UserProfile.objects.all()[0] to = user.email # Confirm there's nothing in the DB and we're using the default eq_(UserNotification.objects.count(), 0) # Make sure that this is True by default setting = mkt.users.notifications.NOTIFICATIONS_BY_SHORT['reply'] eq_(setting.default_checked, True) success = send_mail('test subject', 'test body', perm_setting='reply', recipient_list=[to], fail_silently=False) assert success, "Email wasn't sent" eq_(len(mail.outbox), 1)
def test_async_will_retry(self, backend): backend.side_effect = self.make_backend_class([True, True, False]) with self.assertRaises(RuntimeError): send_mail("test subject", "test body", recipient_list=["*****@*****.**"]) assert send_mail("test subject", "test body", async=True, recipient_list=["*****@*****.**"])
def _review(request, addon, version): if (not settings.ALLOW_SELF_REVIEWS and not acl.action_allowed(request, 'Admin', '%') and addon.has_author(request.user)): messages.warning(request, _('Self-reviews are not allowed.')) return redirect(reverse('reviewers.home')) if (addon.status == mkt.STATUS_BLOCKED and not acl.action_allowed(request, 'Apps', 'ReviewEscalated')): messages.warning( request, _('Only senior reviewers can review blocklisted apps.')) return redirect(reverse('reviewers.home')) attachment_formset = CommAttachmentFormSet(data=request.POST or None, files=request.FILES or None, prefix='attachment') testedon_formset = TestedOnFormSet(data=request.POST or None, prefix='testedon') form = forms.get_review_form(data=request.POST or None, files=request.FILES or None, request=request, addon=addon, version=version, attachment_formset=attachment_formset, testedon_formset=testedon_formset) postdata = request.POST if request.method == 'POST' else None all_forms = [form, attachment_formset, testedon_formset] if version: features_list = version.features.to_names() appfeatures_form = AppFeaturesForm(data=postdata, instance=version.features) all_forms.append(appfeatures_form) else: appfeatures_form = None features_list = None queue_type = form.helper.review_type redirect_url = reverse('reviewers.apps.queue_%s' % queue_type) is_admin = acl.action_allowed(request, 'Apps', 'Edit') if request.method == 'POST' and all(f.is_valid() for f in all_forms): if form.cleaned_data.get('action') == 'public': old_types = set(o.id for o in addon.device_types) new_types = set(form.cleaned_data.get('device_override')) if old_types != new_types: # The reviewer overrode the device types. We need to not # publish this app immediately. if addon.publish_type == mkt.PUBLISH_IMMEDIATE: addon.update(publish_type=mkt.PUBLISH_PRIVATE) # And update the device types to what the reviewer set. AddonDeviceType.objects.filter(addon=addon).delete() for device in form.cleaned_data.get('device_override'): addon.addondevicetype_set.create(device_type=device) # Log that the reviewer changed the device types. added_devices = new_types - old_types removed_devices = old_types - new_types msg_list = [ _(u'Added {0}').format(unicode(mkt.DEVICE_TYPES[d].name)) for d in added_devices ] + [ _(u'Removed {0}').format(unicode(mkt.DEVICE_TYPES[d].name)) for d in removed_devices ] msg = _(u'Device(s) changed by ' u'reviewer: {0}').format(', '.join(msg_list)) log_reviewer_action(addon, request.user, msg, mkt.LOG.REVIEW_DEVICE_OVERRIDE) if appfeatures_form.changed_data: # The reviewer overrode the requirements. We need to not # publish this app immediately. if addon.publish_type == mkt.PUBLISH_IMMEDIATE: addon.update(publish_type=mkt.PUBLISH_PRIVATE) appfeatures_form.save(mark_for_rereview=False) # Log that the reviewer changed the minimum requirements. added_features, removed_features = (appfeatures_form .get_changed_features()) fmt = ', '.join( [_(u'Added {0}').format(f) for f in added_features] + [_(u'Removed {0}').format(f) for f in removed_features]) # L10n: {0} is the list of requirements changes. msg = _(u'Requirements changed by reviewer: {0}').format(fmt) log_reviewer_action(addon, request.user, msg, mkt.LOG.REVIEW_FEATURES_OVERRIDE) score = form.helper.process() if form.cleaned_data.get('is_showcase'): if not addon.tags.filter(tag_text=SHOWCASE_TAG).exists(): Tag(tag_text=SHOWCASE_TAG).save_tag(addon) recipient_list = (settings.APP_CURATION_BOARD_EMAIL,) subject = u'App [%s] nominated to be featured' % addon.name msg = (u'The Marketplace reviewer %s thinks %s (%s%s) is' u'good enough to be a featured app.\n\n' % ( request.user, addon.name, settings.SITE_URL, addon.get_url_path())) send_mail(subject, msg, recipient_list=recipient_list) else: Tag(tag_text=SHOWCASE_TAG).remove_tag(addon) # Success message. if score: score = ReviewerScore.objects.filter(user=request.user)[0] # L10N: {0} is the type of review. {1} is the points they earned. # {2} is the points they now have total. success = _( u'"{0}" successfully processed (+{1} points, {2} total).' .format(unicode(mkt.REVIEWED_CHOICES[score.note_key]), score.score, ReviewerScore.get_total(request.user))) else: success = _('Review successfully processed.') messages.success(request, success) return redirect(redirect_url) canned = CannedResponse.objects.all() actions = form.helper.actions.items() try: if not version: raise Version.DoesNotExist show_diff = (addon.versions.exclude(id=version.id) .filter(files__isnull=False, created__lt=version.created, files__status=mkt.STATUS_PUBLIC) .latest()) except Version.DoesNotExist: show_diff = None # The actions we should show a minimal form from. actions_minimal = [k for (k, a) in actions if not a.get('minimal')] # We only allow the user to check/uncheck files for "pending" allow_unchecking_files = form.helper.review_type == "pending" versions = (Version.with_deleted.filter(addon=addon) .order_by('-created') .transform(Version.transformer_activity) .transform(Version.transformer)) product_attrs = { 'product': json.dumps( product_as_dict(request, addon, False, 'reviewer'), cls=JSONEncoder), 'manifest_url': addon.manifest_url, } pager = paginate(request, versions, 10) num_pages = pager.paginator.num_pages count = pager.paginator.count ctx = context(request, version=version, product=addon, pager=pager, num_pages=num_pages, count=count, form=form, canned=canned, is_admin=is_admin, status_types=mkt.STATUS_CHOICES, show_diff=show_diff, allow_unchecking_files=allow_unchecking_files, actions=actions, actions_minimal=actions_minimal, tab=queue_type, product_attrs=product_attrs, attachment_formset=attachment_formset, appfeatures_form=appfeatures_form, testedon_formset=testedon_formset) if features_list is not None: ctx['feature_list'] = features_list return render(request, 'reviewers/review.html', ctx)
def test_send_string(self): to = "*****@*****.**" with self.assertRaises(ValueError): send_mail("subj", "body", recipient_list=to)
def _review(request, addon, version): if (not settings.ALLOW_SELF_REVIEWS and not acl.action_allowed(request, 'Admin', '%') and addon.has_author(request.user)): messages.warning(request, _('Self-reviews are not allowed.')) return redirect(reverse('reviewers.home')) if (addon.status == mkt.STATUS_BLOCKED and not acl.action_allowed(request, 'Apps', 'ReviewEscalated')): messages.warning( request, _('Only senior reviewers can review blocklisted apps.')) return redirect(reverse('reviewers.home')) attachment_formset = CommAttachmentFormSet(data=request.POST or None, files=request.FILES or None, prefix='attachment') testedon_formset = TestedOnFormSet(data=request.POST or None, prefix='testedon') form = forms.get_review_form(data=request.POST or None, files=request.FILES or None, request=request, addon=addon, version=version, attachment_formset=attachment_formset, testedon_formset=testedon_formset) postdata = request.POST if request.method == 'POST' else None all_forms = [form, attachment_formset, testedon_formset] if version: features_list = version.features.to_names() appfeatures_form = AppFeaturesForm(data=postdata, instance=version.features) all_forms.append(appfeatures_form) else: appfeatures_form = None features_list = None queue_type = form.helper.review_type redirect_url = reverse('reviewers.apps.queue_%s' % queue_type) is_admin = acl.action_allowed(request, 'Apps', 'Edit') if request.method == 'POST' and all(f.is_valid() for f in all_forms): if form.cleaned_data.get('action') == 'public': old_types = set(o.id for o in addon.device_types) new_types = set(form.cleaned_data.get('device_override')) if old_types != new_types: # The reviewer overrode the device types. We need to not # publish this app immediately. if addon.publish_type == mkt.PUBLISH_IMMEDIATE: addon.update(publish_type=mkt.PUBLISH_PRIVATE) # And update the device types to what the reviewer set. AddonDeviceType.objects.filter(addon=addon).delete() for device in form.cleaned_data.get('device_override'): addon.addondevicetype_set.create(device_type=device) # Log that the reviewer changed the device types. added_devices = new_types - old_types removed_devices = old_types - new_types msg_list = [ _(u'Added {0}').format(unicode(mkt.DEVICE_TYPES[d].name)) for d in added_devices ] + [ _(u'Removed {0}').format(unicode(mkt.DEVICE_TYPES[d].name)) for d in removed_devices ] msg = _(u'Device(s) changed by ' u'reviewer: {0}').format(', '.join(msg_list)) log_reviewer_action(addon, request.user, msg, mkt.LOG.REVIEW_DEVICE_OVERRIDE) if appfeatures_form.changed_data: # The reviewer overrode the requirements. We need to not # publish this app immediately. if addon.publish_type == mkt.PUBLISH_IMMEDIATE: addon.update(publish_type=mkt.PUBLISH_PRIVATE) appfeatures_form.save(mark_for_rereview=False) # Log that the reviewer changed the minimum requirements. added_features, removed_features = ( appfeatures_form.get_changed_features()) fmt = ', '.join( [_(u'Added {0}').format(f) for f in added_features] + [_(u'Removed {0}').format(f) for f in removed_features]) # L10n: {0} is the list of requirements changes. msg = _(u'Requirements changed by reviewer: {0}').format(fmt) log_reviewer_action(addon, request.user, msg, mkt.LOG.REVIEW_FEATURES_OVERRIDE) score = form.helper.process() if form.cleaned_data.get('is_showcase'): if not addon.tags.filter(tag_text=SHOWCASE_TAG).exists(): Tag(tag_text=SHOWCASE_TAG).save_tag(addon) recipient_list = (settings.APP_CURATION_BOARD_EMAIL, ) subject = u'App [%s] nominated to be featured' % addon.name msg = (u'The Marketplace reviewer %s thinks %s (%s%s) is' u'good enough to be a featured app.\n\n' % (request.user, addon.name, settings.SITE_URL, addon.get_url_path())) send_mail(subject, msg, recipient_list=recipient_list) else: Tag(tag_text=SHOWCASE_TAG).remove_tag(addon) # Success message. if score: score = ReviewerScore.objects.filter(user=request.user)[0] # L10N: {0} is the type of review. {1} is the points they earned. # {2} is the points they now have total. success = _( u'"{0}" successfully processed (+{1} points, {2} total).'. format(unicode(mkt.REVIEWED_CHOICES[score.note_key]), score.score, ReviewerScore.get_total(request.user))) else: success = _('Review successfully processed.') messages.success(request, success) return redirect(redirect_url) canned = CannedResponse.objects.all() actions = form.helper.actions.items() try: if not version: raise Version.DoesNotExist show_diff = (addon.versions.exclude(id=version.id).filter( files__isnull=False, created__lt=version.created, files__status=mkt.STATUS_PUBLIC).latest()) except Version.DoesNotExist: show_diff = None # The actions we should show a minimal form from. actions_minimal = [k for (k, a) in actions if not a.get('minimal')] # We only allow the user to check/uncheck files for "pending" allow_unchecking_files = form.helper.review_type == "pending" versions = (Version.with_deleted.filter( addon=addon).order_by('-created').transform( Version.transformer_activity).transform(Version.transformer)) product_attrs = { 'product': json.dumps(product_as_dict(request, addon, False, 'reviewer'), cls=JSONEncoder), 'manifest_url': addon.manifest_url, } pager = paginate(request, versions, 10) num_pages = pager.paginator.num_pages count = pager.paginator.count ctx = context(request, version=version, product=addon, pager=pager, num_pages=num_pages, count=count, form=form, canned=canned, is_admin=is_admin, status_types=mkt.STATUS_CHOICES, show_diff=show_diff, allow_unchecking_files=allow_unchecking_files, actions=actions, actions_minimal=actions_minimal, tab=queue_type, product_attrs=product_attrs, attachment_formset=attachment_formset, appfeatures_form=appfeatures_form, testedon_formset=testedon_formset) if features_list is not None: ctx['feature_list'] = features_list return render(request, 'reviewers/review.html', ctx)
def test_send_multilines_subjects(self): send_mail('test\nsubject', 'test body', from_email='*****@*****.**', recipient_list=['*****@*****.**']) eq_('test subject', mail.outbox[0].subject, 'Subject not stripped')
def test_send_string(self): to = '*****@*****.**' with self.assertRaises(ValueError): send_mail('subj', 'body', recipient_list=to)
def test_send_multilines_subjects(self): send_mail("test\nsubject", "test body", from_email="*****@*****.**", recipient_list=["*****@*****.**"]) eq_("test subject", mail.outbox[0].subject, "Subject not stripped")
def test_success_real_mail(self): assert send_mail("test subject", "test body", recipient_list=["*****@*****.**"], fail_silently=False) eq_(len(mail.outbox), 1) eq_(mail.outbox[0].subject.find("test subject"), 0) eq_(mail.outbox[0].body.find("test body"), 0)