Example #1
0
    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
            }
        ))
Example #3
0
 def handle(self):
     self.reply(distro_tracker_render_to_string('control/help.txt', {
         'descriptions': [
             command.META.get('description', '')
             for command in UNIQUE_COMMANDS
         ],
     }))
Example #4
0
    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)
Example #5
0
 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'
     )
Example #6
0
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)
Example #7
0
 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,
     })