def _ask_confirmation(self, email, commands, messages): """ Sends a confirmation mail to a single user. Includes all commands that the user needs to confirm. """ command_confirmation = CommandConfirmation.objects.create_for_commands( commands=commands) message = distro_tracker_render_to_string( 'control/email-confirmation-required.txt', { 'command_confirmation': command_confirmation, 'confirmation_messages': self.confirmation_messages[email], } ) subject = 'CONFIRM ' + command_confirmation.confirmation_key EmailMessage( subject=subject, to=[email], from_email=DISTRO_TRACKER_BOUNCES_EMAIL, headers={ 'From': DISTRO_TRACKER_CONTROL_EMAIL, }, body=message, ).send() logger.info("control => confirmation token sent to %s", email)
def test_bounce_over_limit(self): """ Tests that all the user's subscriptions are dropped when too many bounces are received. """ # Set up some prior bounces - one each day. date = timezone.now().date() for days in range(1, settings.DISTRO_TRACKER_MAX_DAYS_TOLERATE_BOUNCE): self.add_sent(self.user, date - timedelta(days=days)) self.add_bounce(self.user, date - timedelta(days=days)) # Set up a sent mail today. self.add_sent(self.user, date) # Make sure there were at least some subscriptions packages_subscribed_to = [ subscription.package.name for subscription in self.user.emailsettings.subscription_set.all() ] self.assertTrue(len(packages_subscribed_to) > 0) # Receive a bounce message. dispatch.handle_bounces(self.create_bounce_address(self.user.email)) # Assert that the user's subscriptions have been dropped. self.assertEqual(self.user.emailsettings.subscription_set.count(), 0) # A notification was sent to the user. self.assertEqual(len(mail.outbox), 1) self.assertIn(self.user.email, mail.outbox[0].to) # Check that the content of the email is correct. self.assertEqual(mail.outbox[0].body, distro_tracker_render_to_string( 'dispatch/unsubscribed-due-to-bounces-email.txt', { 'email': self.user.email, 'packages': packages_subscribed_to } ))
def handle(self): self.reply(distro_tracker_render_to_string('control/help.txt', { 'descriptions': [ command.META.get('description', '') for command in UNIQUE_COMMANDS ], }))
def post(self, request, slug): self.team = get_object_or_404(Team, slug=slug) if self.team.owner != request.user: raise PermissionDenied form = AddTeamMemberForm(request.POST) if form.is_valid(): email = form.cleaned_data['email'] # Emails that do not exist should be created user, _ = UserEmail.objects.get_or_create(email=email) # The membership is muted by default until the user confirms it membership = self.team.add_members([user], muted=True)[0] confirmation = MembershipConfirmation.objects.create_confirmation( membership=membership) send_mail( 'Team Membership Confirmation', distro_tracker_render_to_string( 'core/email-team-membership-confirmation.txt', { 'confirmation': confirmation, 'team': self.team, }), from_email=settings.DISTRO_TRACKER_CONTACT_EMAIL, recipient_list=[email]) return redirect('dtracker-team-manage', slug=self.team.slug)
def get_confirmation_message(self): """ :returns: A message giving additional information about unsubscribing from all packages. :rtype: string """ return distro_tracker_render_to_string( 'control/email-unsubscribeall-confirmation.txt' )
def handle_bounces(sent_to_address, message): """ Handles a received bounce message. :param sent_to_address: The envelope-to (return path) address to which the bounced email was returned. :type sent_to_address: string """ bounce_email, user_email = verp.decode(sent_to_address) match = re.match(r'^bounces\+(\d{8})@' + DISTRO_TRACKER_FQDN, bounce_email) if not match: logger.warning('bounces :: invalid address %s', bounce_email) return try: date = datetime.strptime(match.group(1), '%Y%m%d') except ValueError: logger.warning('bounces :: invalid date in address %s', bounce_email) return logger.info('bounces :: received one for %s/%s', user_email, date) try: user = UserEmailBounceStats.objects.get(email__iexact=user_email) except UserEmailBounceStats.DoesNotExist: logger.warning('bounces :: unknown user email %s', user_email) return if bounce_is_for_spam(message): logger.info('bounces :: discarded spam bounce for %s/%s', user_email, date) return UserEmailBounceStats.objects.add_bounce_for_user(email=user_email, date=date) if user.has_too_many_bounces(): logger.info('bounces => %s has too many bounces', user_email) packages = [p.name for p in user.emailsettings.packagename_set.all()] email_body = distro_tracker_render_to_string( 'dispatch/unsubscribed-due-to-bounces-email.txt', { 'email': user_email, 'packages': packages, }) EmailMessage( subject='All your package subscriptions have been cancelled', from_email=settings.DISTRO_TRACKER_BOUNCES_LIKELY_SPAM_EMAIL, to=[user_email], cc=[settings.DISTRO_TRACKER_CONTACT_EMAIL], body=email_body, headers={ 'From': settings.DISTRO_TRACKER_CONTACT_EMAIL, }, ).send() user.emailsettings.unsubscribe_all() for package in packages: logger.info('bounces :: removed %s from %s', user_email, package)
def get_confirmation_message(self): """ :returns: A message giving additional information about subscribing to a package. :rtype: string """ return distro_tracker_render_to_string( 'control/email-subscription-confirmation.txt', { 'package': self.package, } )
def get_confirmation_email_content(self, confirmation): return distro_tracker_render_to_string(self.confirmation_email_template, { 'confirmation': confirmation, })