Exemple #1
0
    def after(self, event, state):
        mail_plugin = plugins.get('mail')
        if not mail_plugin.is_enabled(event.project):
            return

        username = self.get_option('username')
        try:
            user = User.objects.get(username=username)
        except:
            return

        project = event.project
        group = event.group

        subject_prefix = mail_plugin.get_option('subject_prefix', project) or settings.EMAIL_SUBJECT_PREFIX

        interface_list = []
        for interface in event.interfaces.itervalues():
            body = interface.to_email_html(event)
            if not body:
                continue
            interface_list.append((interface.get_title(), mark_safe(body)))

        subject = group.get_email_subject()

        link = group.get_absolute_url()

        template = 'sentry/emails/error.txt'
        html_template = 'sentry/emails/error.html'

        context = {
            'group': group,
            'event': event,
            'tags': event.get_tags(),
            'link': link,
            'interfaces': interface_list,
            'rule': None,
            'rule_link': None,
        }

        headers = {
            'X-Sentry-Logger': group.logger,
            'X-Sentry-Logger-Level': group.get_level_display(),
            'X-Sentry-Project': project.name,
            'X-Sentry-Reply-To': group_id_to_email(group.id),
        }

        msg = MessageBuilder(
            subject='%s%s' % (subject_prefix, subject),
            template=template,
            html_template=html_template,
            body=body,
            headers=headers,
            context=context,
            reference=group,
        )


        msg.add_users([user.id], project=project)
        return msg.send()
Exemple #2
0
    def notify(self, notification):
        event = notification.event
        group = event.group
        project = group.project
        org = group.organization

        subject = group.get_email_subject()

        link = group.get_absolute_url()

        template = "sentry/emails/error.txt"
        html_template = "sentry/emails/error.html"

        rules = []
        for rule in notification.rules:
            rule_link = reverse("sentry-edit-project-rule", args=[org.slug, project.slug, rule.id])
            rules.append((rule.label, rule_link))

        enhanced_privacy = org.flags.enhanced_privacy

        context = {
            "project_label": project.get_full_name(),
            "group": group,
            "event": event,
            "link": link,
            "rules": rules,
            "enhanced_privacy": enhanced_privacy,
        }

        # if the organization has enabled enhanced privacy controls we dont send
        # data which may show PII or source code
        if not enhanced_privacy:
            interface_list = []
            for interface in event.interfaces.itervalues():
                body = interface.to_email_html(event)
                if not body:
                    continue
                text_body = interface.to_string(event)
                interface_list.append((interface.get_title(), mark_safe(body), text_body))

            context.update({"tags": event.get_tags(), "interfaces": interface_list})

        headers = {
            "X-Sentry-Logger": group.logger,
            "X-Sentry-Logger-Level": group.get_level_display(),
            "X-Sentry-Team": project.team.name,
            "X-Sentry-Project": project.name,
            "X-Sentry-Reply-To": group_id_to_email(group.id),
        }

        self._send_mail(
            subject=subject,
            template=template,
            html_template=html_template,
            project=project,
            reference=group,
            headers=headers,
            context=context,
        )
Exemple #3
0
    def notify(self, notification):
        event = notification.event
        group = event.group
        project = group.project

        interface_list = []
        for interface in event.interfaces.itervalues():
            body = interface.to_email_html(event)
            if not body:
                continue
            text_body = interface.to_string(event)
            interface_list.append(
                (interface.get_title(), mark_safe(body), text_body)
            )

        subject = group.get_email_subject()

        link = group.get_absolute_url()

        template = 'sentry/emails/error.txt'
        html_template = 'sentry/emails/error.html'

        rules = []
        for rule in notification.rules:
            rule_link = reverse('sentry-edit-project-rule', args=[
                group.organization.slug, project.slug, rule.id
            ])
            rules.append((rule.label, rule_link))

        context = {
            'project_label': project.get_full_name(),
            'group': group,
            'event': event,
            'tags': event.get_tags(),
            'link': link,
            'interfaces': interface_list,
            'rules': rules,
        }

        headers = {
            'X-Sentry-Logger': group.logger,
            'X-Sentry-Logger-Level': group.get_level_display(),
            'X-Sentry-Team': project.team.name,
            'X-Sentry-Project': project.name,
            'X-Sentry-Reply-To': group_id_to_email(group.id),
        }

        self._send_mail(
            subject=subject,
            template=template,
            html_template=html_template,
            project=project,
            group=group,
            headers=headers,
            context=context,
        )
Exemple #4
0
    def notify(self, notification):
        event = notification.event
        group = event.group
        project = group.project

        interface_list = []
        for interface in event.interfaces.itervalues():
            body = interface.to_email_html(event)
            if not body:
                continue
            text_body = interface.to_string(event)
            interface_list.append(
                (interface.get_title(), mark_safe(body), text_body)
            )

        subject = group.get_email_subject()

        link = group.get_absolute_url()

        template = 'sentry/emails/error.txt'
        html_template = 'sentry/emails/error.html'

        rules = []
        for rule in notification.rules:
            rule_link = reverse('sentry-edit-project-rule', args=[
                group.organization.slug, project.slug, rule.id
            ])
            rules.append((rule.label, rule_link))

        context = {
            'project_label': project.get_full_name(),
            'group': group,
            'event': event,
            'tags': event.get_tags(),
            'link': link,
            'interfaces': interface_list,
            'rules': rules,
        }

        headers = {
            'X-Sentry-Logger': group.logger,
            'X-Sentry-Logger-Level': group.get_level_display(),
            'X-Sentry-Team': project.team.name,
            'X-Sentry-Project': project.name,
            'X-Sentry-Reply-To': group_id_to_email(group.id),
        }

        self._send_mail(
            subject=subject,
            template=template,
            html_template=html_template,
            project=project,
            group=group,
            headers=headers,
            context=context,
        )
Exemple #5
0
    def notify_users(self, group, event, fail_silently=False):
        project = group.project

        interface_list = []
        for interface in event.interfaces.itervalues():
            body = interface.to_email_html(event)
            if not body:
                continue
            interface_list.append((interface.get_title(), mark_safe(body)))

        subject = '[%s] %s: %s' % (
            project.name.encode('utf-8'),
            unicode(event.get_level_display()).upper().encode('utf-8'),
            event.error().encode('utf-8').splitlines()[0])

        url_prefix = settings.URL_PREFIX
        parsed = urlparse.urlparse(url_prefix)
        url_prefix = "%s://%s" % (parsed.scheme, parsed.netloc)
        link = '%s%s' % (url_prefix,
            reverse('sentry-group', args=[group.team.slug, group.project.slug, group.id]))

        template = 'sentry/emails/error.txt'
        html_template = 'sentry/emails/error.html'

        context = {
            'group': group,
            'event': event,
            'link': link,
            'interfaces': interface_list,
            'settings_link': self.get_notification_settings_url(),
        }

        headers = {
            'X-Sentry-Logger': event.logger,
            'X-Sentry-Logger-Level': event.get_level_display(),
            'X-Sentry-Project': project.name,
            'X-Sentry-Server': event.server_name,
            'X-Sentry-Reply-To': group_id_to_email(group.pk),
        }

        self._send_mail(
            subject=subject,
            template=template,
            html_template=html_template,
            project=project,
            fail_silently=fail_silently,
            headers=headers,
            context=context,
        )
Exemple #6
0
    def get_headers(self):
        project = self.project
        group = self.group

        headers = {"X-Sentry-Project": project.slug}

        if group:
            headers.update({
                "X-Sentry-Logger": group.logger,
                "X-Sentry-Logger-Level": group.get_level_display(),
                "X-Sentry-Reply-To": group_id_to_email(group.id),
                "category": self.get_category(),
            })

        return headers
Exemple #7
0
def get_headers(notification: BaseNotification) -> Mapping[str, Any]:
    headers = {
        "X-Sentry-Project": notification.project.slug,
        "X-SMTPAPI": json.dumps({"category": notification.get_category()}),
    }

    group = getattr(notification, "group", None)
    if group:
        headers.update({
            "X-Sentry-Logger": group.logger,
            "X-Sentry-Logger-Level": group.get_level_display(),
            "X-Sentry-Reply-To": group_id_to_email(group.id),
        })

    return headers
    def send_notification(self):
        from sentry.utils.email import MessageBuilder, group_id_to_email

        if not self.group_id:
            return

        if self.type not in (Activity.NOTE, Activity.ASSIGNED):
            return

        send_to = self.get_recipients()

        if not send_to:
            return

        author = self.user.first_name or self.user.username

        subject_prefix = self.project.get_option('subject_prefix',
                                                 settings.EMAIL_SUBJECT_PREFIX)
        if subject_prefix:
            subject_prefix = subject_prefix.rstrip() + ' '

        subject = '%s%s' % (subject_prefix, self.group.get_email_subject())

        context = {
            'data': self.data,
            'author': author,
            'group': self.group,
            'link': self.group.get_absolute_url(),
        }

        headers = {
            'X-Sentry-Reply-To': group_id_to_email(self.group.id),
        }

        template_name = self.get_type_display()

        msg = MessageBuilder(
            subject=subject,
            context=context,
            template='sentry/emails/activity/{}.txt'.format(template_name),
            html_template='sentry/emails/activity/{}.html'.format(
                template_name),
            headers=headers,
            reference=self,
            reply_reference=self.group,
        )
        msg.add_users(send_to, project=self.project)
        msg.send_async()
Exemple #9
0
    def get_headers(self):
        project = self.project
        group = self.group

        headers = {
            'X-Sentry-Project': project.slug,
        }

        if group:
            headers.update({
                'X-Sentry-Logger': group.logger,
                'X-Sentry-Logger-Level': group.get_level_display(),
                'X-Sentry-Reply-To': group_id_to_email(group.id),
            })

        return headers
Exemple #10
0
    def send_notification(self):
        from sentry.utils.email import MessageBuilder, group_id_to_email

        if not self.group_id:
            return

        if self.type not in (Activity.NOTE, Activity.ASSIGNED):
            return

        send_to = self.get_recipients()

        if not send_to:
            return

        author = self.user.first_name or self.user.username

        subject_prefix = self.project.get_option(
            'subject_prefix', settings.EMAIL_SUBJECT_PREFIX)
        if subject_prefix:
            subject_prefix = subject_prefix.rstrip() + ' '

        subject = '%s%s' % (subject_prefix, self.group.get_email_subject())

        context = {
            'data': self.data,
            'author': author,
            'group': self.group,
            'link': self.group.get_absolute_url(),
        }

        headers = {
            'X-Sentry-Reply-To': group_id_to_email(self.group.id),
        }

        template_name = self.get_type_display()

        msg = MessageBuilder(
            subject=subject,
            context=context,
            template='sentry/emails/activity/{}.txt'.format(template_name),
            html_template='sentry/emails/activity/{}.html'.format(template_name),
            headers=headers,
            reference=self,
            reply_reference=self.group,
        )
        msg.add_users(send_to, project=self.project)
        msg.send_async()
Exemple #11
0
    def get_headers(self):
        project = self.project
        group = self.group

        headers = {
            'X-Sentry-Team': project.team.slug,
            'X-Sentry-Project': project.slug,
        }

        if group:
            headers.update({
                'X-Sentry-Logger': group.logger,
                'X-Sentry-Logger-Level': group.get_level_display(),
                'X-Sentry-Reply-To': group_id_to_email(group.id),
            })

        return headers
Exemple #12
0
    def get_headers(self) -> Mapping[str, Any]:
        project = self.project
        group = self.group

        headers = {
            "X-Sentry-Project": project.slug,
            "X-SMTPAPI": json.dumps({"category": self.get_category()}),
        }

        if group:
            headers.update({
                "X-Sentry-Logger": group.logger,
                "X-Sentry-Logger-Level": group.get_level_display(),
                "X-Sentry-Reply-To": group_id_to_email(group.id),
            })

        return headers
Exemple #13
0
    def notify_users(self, group, event, fail_silently=False):
        project = group.project

        interface_list = []
        for interface in event.interfaces.itervalues():
            body = interface.to_email_html(event)
            if not body:
                continue
            interface_list.append((interface.get_title(), mark_safe(body)))

        subject = '[%s] %s: %s' % (
            project.name.encode('utf-8'),
            unicode(event.get_level_display()).upper().encode('utf-8'),
            event.error().encode('utf-8').splitlines()[0])

        link = group.get_absolute_url()

        template = 'sentry/emails/error.txt'
        html_template = 'sentry/emails/error.html'

        context = {
            'group': group,
            'event': event,
            'tags': event.get_tags(),
            'link': link,
            'interfaces': interface_list,
        }

        headers = {
            'X-Sentry-Logger': event.logger,
            'X-Sentry-Logger-Level': event.get_level_display(),
            'X-Sentry-Project': project.name,
            'X-Sentry-Server': event.server_name,
            'X-Sentry-Reply-To': group_id_to_email(group.pk),
        }

        self._send_mail(
            subject=subject,
            template=template,
            html_template=html_template,
            project=project,
            fail_silently=fail_silently,
            headers=headers,
            context=context,
        )
Exemple #14
0
    def notify_users(self, group, event, fail_silently=False):
        project = group.project

        interface_list = []
        for interface in event.interfaces.itervalues():
            body = interface.to_email_html(event)
            if not body:
                continue
            interface_list.append((interface.get_title(), mark_safe(body)))

        subject = '[%s] %s: %s' % (
            project.name.encode('utf-8'),
            unicode(event.get_level_display()).upper().encode('utf-8'),
            event.error().encode('utf-8').splitlines()[0])

        link = group.get_absolute_url()

        template = 'sentry/emails/error.txt'
        html_template = 'sentry/emails/error.html'

        context = {
            'group': group,
            'event': event,
            'tags': event.get_tags(),
            'link': link,
            'interfaces': interface_list,
        }

        headers = {
            'X-Sentry-Logger': event.logger,
            'X-Sentry-Logger-Level': event.get_level_display(),
            'X-Sentry-Project': project.name,
            'X-Sentry-Server': event.server_name,
            'X-Sentry-Reply-To': group_id_to_email(group.pk),
        }

        self._send_mail(
            subject=subject,
            template=template,
            html_template=html_template,
            project=project,
            fail_silently=fail_silently,
            headers=headers,
            context=context,
        )
Exemple #15
0
    def notify(self, notification):
        event = notification.event
        group = event.group
        project = group.project
        org = group.organization

        subject = group.get_email_subject()

        link = group.get_absolute_url()

        template = 'sentry/emails/error.txt'
        html_template = 'sentry/emails/error.html'

        rules = []
        for rule in notification.rules:
            rule_link = reverse('sentry-edit-project-rule', args=[
                org.slug, project.slug, rule.id
            ])
            rules.append((rule.label, rule_link))

        enhanced_privacy = org.flags.enhanced_privacy

        context = {
            'project_label': project.get_full_name(),
            'group': group,
            'event': event,
            'link': link,
            'rules': rules,
            'enhanced_privacy': enhanced_privacy,
        }

        # if the organization has enabled enhanced privacy controls we dont send
        # data which may show PII or source code
        if not enhanced_privacy:
            interface_list = []
            for interface in event.interfaces.itervalues():
                body = interface.to_email_html(event)
                if not body:
                    continue
                text_body = interface.to_string(event)
                interface_list.append(
                    (interface.get_title(), mark_safe(body), text_body)
                )

            context.update({
                'tags': event.get_tags(),
                'interfaces': interface_list,
            })

        headers = {
            'X-Sentry-Logger': group.logger,
            'X-Sentry-Logger-Level': group.get_level_display(),
            'X-Sentry-Team': project.team.name,
            'X-Sentry-Project': project.name,
            'X-Sentry-Reply-To': group_id_to_email(group.id),
        }

        for user_id in self.get_send_to(project):
            self.add_unsubscribe_link(context, user_id, project)
            self._send_mail(
                subject=subject,
                template=template,
                html_template=html_template,
                project=project,
                reference=group,
                headers=headers,
                context=context,
                send_to=[user_id],
            )
Exemple #16
0
    def notify_about_activity(self, activity):
        if activity.type not in (Activity.NOTE, Activity.ASSIGNED, Activity.RELEASE):
            return

        candidate_ids = set(self.get_send_to(activity.project))

        # Never send a notification to the user that performed the action.
        candidate_ids.discard(activity.user_id)

        if activity.type == Activity.ASSIGNED:
            # Only notify the assignee, and only if they are in the candidate set.
            recipient_ids = candidate_ids & set(map(int, (activity.data['assignee'],)))
        elif activity.type == Activity.NOTE:
            recipient_ids = candidate_ids - set(
                UserOption.objects.filter(
                    user__in=candidate_ids,
                    key='subscribe_notes',
                    value=u'0',
                ).values_list('user', flat=True)
            )
        else:
            recipient_ids = candidate_ids

        if not recipient_ids:
            return

        project = activity.project
        org = project.organization
        group = activity.group

        headers = {}

        context = {
            'data': activity.data,
            'author': activity.user,
            'project': project,
            'project_link': absolute_uri(reverse('sentry-stream', kwargs={
                'organization_slug': org.slug,
                'project_id': project.slug,
            })),
        }

        if group:
            group_link = absolute_uri('/{}/{}/issues/{}/'.format(
                org.slug, project.slug, group.id
            ))
            activity_link = '{}activity/'.format(group_link)

            headers.update({
                'X-Sentry-Reply-To': group_id_to_email(group.id),
            })

            context.update({
                'group': group,
                'link': group_link,
                'activity_link': activity_link,
            })

        # TODO(dcramer): abstract each activity email into its own helper class
        if activity.type == Activity.RELEASE:
            context.update({
                'release': Release.objects.get(
                    version=activity.data['version'],
                    project=project,
                ),
                'release_link': absolute_uri('/{}/{}/releases/{}/'.format(
                    org.slug,
                    project.slug,
                    activity.data['version'],
                )),
            })

        template_name = activity.get_type_display()

        if group:
            subject = group.get_email_subject()
        elif activity.type == Activity.RELEASE:
            subject = 'Release %s' % activity.data['version']
        else:
            raise NotImplementedError

        self._send_mail(
            project=project,
            send_to=recipient_ids,
            subject=subject,
            context=context,
            template='sentry/emails/activity/{}.txt'.format(template_name),
            html_template='sentry/emails/activity/{}.html'.format(template_name),
            headers=headers,
            reference=activity,
            reply_reference=group,
        )
Exemple #17
0
    def send_notification(self):
        from sentry.models import Release
        from sentry.utils.email import MessageBuilder, group_id_to_email

        if self.type not in (Activity.NOTE, Activity.ASSIGNED, Activity.RELEASE):
            return

        send_to = self.get_recipients()

        if not send_to:
            return

        project = self.project
        org = self.project.organization
        group = self.group

        if self.user:
            author = self.user.first_name or self.user.username
        else:
            author = None

        subject_prefix = self.project.get_option(
            'subject_prefix', settings.EMAIL_SUBJECT_PREFIX)
        if subject_prefix:
            subject_prefix = subject_prefix.rstrip() + ' '

        if self.group:
            subject = '%s%s' % (subject_prefix, self.group.get_email_subject())
        elif self.type == Activity.RELEASE:
            subject = '%sRelease %s' % (subject_prefix, self.data['version'])
        else:
            raise NotImplementedError

        headers = {}

        context = {
            'data': self.data,
            'author': author,
            'project': project,
            'project_link': absolute_uri(reverse('sentry-stream', kwargs={
                'organization_slug': org.slug,
                'project_id': project.slug,
            })),
        }

        if group:
            group_link = absolute_uri('/{}/{}/group/{}/'.format(org.slug, project.slug, group.id))
            activity_link = '{}activity/'.format(group_link)

            headers.update({
                'X-Sentry-Reply-To': group_id_to_email(group.id),
            })

            context.update({
                'group': group,
                'link': group_link,
                'activity_link': activity_link,
            })

        # TODO(dcramer): abstract each activity email into its own helper class
        if self.type == Activity.RELEASE:
            context.update({
                'release': Release.objects.get(
                    version=self.data['version'],
                    project=project,
                ),
                'release_link': absolute_uri(reverse('sentry-release-details', kwargs={
                    'organization_slug': org.slug,
                    'project_id': project.slug,
                    'version': self.data['version'],
                })),
            })

        template_name = self.get_type_display()

        msg = MessageBuilder(
            subject=subject,
            context=context,
            template='sentry/emails/activity/{}.txt'.format(template_name),
            html_template='sentry/emails/activity/{}.html'.format(template_name),
            headers=headers,
            reference=self,
            reply_reference=self.group,
        )
        msg.add_users(send_to, project=self.project)
        msg.send_async()
Exemple #18
0
 def setUp(self):
     self.address = ('0.0.0.0', 0)
     self.server = SentrySMTPServer(*self.address)
     self.mailto = group_id_to_email(self.group.pk)
Exemple #19
0
    def send_notification(self):
        from sentry.models import Release
        from sentry.utils.email import MessageBuilder, group_id_to_email

        if self.type not in (Activity.NOTE, Activity.ASSIGNED, Activity.RELEASE):
            return

        send_to = self.get_recipients()

        if not send_to:
            return

        project = self.project
        org = self.project.organization

        if self.user:
            author = self.user.first_name or self.user.username
        else:
            author = None

        subject_prefix = self.project.get_option("subject_prefix", settings.EMAIL_SUBJECT_PREFIX)
        if subject_prefix:
            subject_prefix = subject_prefix.rstrip() + " "

        if self.group:
            subject = "%s%s" % (subject_prefix, self.group.get_email_subject())
        elif self.type == Activity.RELEASE:
            subject = "%sRelease %s" % (subject_prefix, self.data["version"])
        else:
            raise NotImplementedError

        headers = {}

        context = {
            "data": self.data,
            "author": author,
            "project": self.project,
            "project_link": absolute_uri(
                reverse("sentry-stream", kwargs={"organization_slug": org.slug, "project_id": project.slug})
            ),
        }

        if self.group:
            headers.update({"X-Sentry-Reply-To": group_id_to_email(self.group.id)})

            context.update({"group": self.group, "link": self.group.get_absolute_url()})

        # TODO(dcramer): abstract each activity email into its own helper class
        if self.type == Activity.RELEASE:
            context.update(
                {
                    "release": Release.objects.get(version=self.data["version"], project=project),
                    "release_link": absolute_uri(
                        reverse(
                            "sentry-release-details",
                            kwargs={
                                "organization_slug": org.slug,
                                "project_id": project.slug,
                                "version": self.data["version"],
                            },
                        )
                    ),
                }
            )

        template_name = self.get_type_display()

        msg = MessageBuilder(
            subject=subject,
            context=context,
            template="sentry/emails/activity/{}.txt".format(template_name),
            html_template="sentry/emails/activity/{}.html".format(template_name),
            headers=headers,
            reference=self,
            reply_reference=self.group,
        )
        msg.add_users(send_to, project=self.project)
        msg.send_async()
Exemple #20
0
    def send_notification(self):
        from sentry.models import User, UserOption
        from sentry.utils.email import MessageBuilder, group_id_to_email

        if self.type != Activity.NOTE or not self.group:
            return

        # TODO(dcramer): some of this logic is duplicated in NotificationPlugin
        # fetch access group members
        user_id_list = set(
            User.objects.filter(accessgroup__projects=self.project,
                                is_active=True).exclude(
                                    id=self.user_id, ).values_list('id',
                                                                   flat=True))

        if self.project.team:
            # fetch team members
            user_id_list |= set(
                u_id for u_id in self.project.team.member_set.filter(
                    user__is_active=True, ).exclude(user__id=self.user_id, ).
                values_list('user', flat=True))

        if not user_id_list:
            return

        disabled = set(
            UserOption.objects.filter(
                user__in=user_id_list,
                key='subscribe_comments',
                value='0',
            ).values_list('user', flat=True))

        send_to = [u_id for u_id in user_id_list if u_id not in disabled]

        if not send_to:
            return

        author = self.user.first_name or self.user.username

        subject = '[%s] %s: %s' % (self.project.name, author,
                                   self.data['text'].splitlines()[0][:64])

        context = {
            'text': self.data['text'],
            'author': author,
            'group': self.group,
            'link': self.group.get_absolute_url(),
        }

        headers = {
            'X-Sentry-Reply-To': group_id_to_email(self.group.pk),
        }

        msg = MessageBuilder(
            subject=subject,
            context=context,
            template='sentry/emails/new_note.txt',
            html_template='sentry/emails/new_note.html',
            headers=headers,
        )
        msg.add_users(send_to, project=self.project)

        try:
            msg.send()
        except Exception, e:
            logger = logging.getLogger('sentry.mail.errors')
            logger.exception(e)
Exemple #21
0
    def send_notification(self):
        from sentry.models import User, UserOption, ProjectOption
        from sentry.utils.email import MessageBuilder, group_id_to_email

        if self.type != Activity.NOTE or not self.group:
            return

        # TODO(dcramer): some of this logic is duplicated in NotificationPlugin
        # fetch access group members
        user_id_list = set(
            User.objects.filter(accessgroup__projects=self.project,
                                is_active=True).exclude(
                                    id=self.user_id, ).values_list('id',
                                                                   flat=True))

        if self.project.team:
            # fetch team members
            user_id_list |= set(
                u_id for u_id in self.project.team.member_set.filter(
                    user__is_active=True, ).exclude(user__id=self.user_id, ).
                values_list('user', flat=True))

        if not user_id_list:
            return

        disabled = set(
            UserOption.objects.filter(
                user__in=user_id_list,
                key='subscribe_notes',
                value=u'0',
            ).values_list('user', flat=True))

        send_to = filter(lambda u_id: u_id not in disabled, user_id_list)

        if not send_to:
            return

        author = self.user.first_name or self.user.username

        subject_prefix = ProjectOption.objects.get_value(
            self.project, 'subject_prefix', settings.EMAIL_SUBJECT_PREFIX)
        if subject_prefix:
            subject_prefix = subject_prefix.rstrip() + ' '

        subject = '%s%s' % (subject_prefix, self.group.get_email_subject())

        context = {
            'text': self.data['text'],
            'author': author,
            'group': self.group,
            'link': self.group.get_absolute_url(),
        }

        headers = {
            'X-Sentry-Reply-To': group_id_to_email(self.group.pk),
        }

        msg = MessageBuilder(
            subject=subject,
            context=context,
            template='sentry/emails/new_note.txt',
            html_template='sentry/emails/new_note.html',
            headers=headers,
            reference=self,
            reply_reference=self.group,
        )
        msg.add_users(send_to, project=self.project)
        msg.send_async()
Exemple #22
0
    def notify_about_activity(self, activity):
        if activity.type not in (Activity.NOTE, Activity.ASSIGNED, Activity.RELEASE):
            return

        candidate_ids = set(self.get_send_to(activity.project))

        # Never send a notification to the user that performed the action.
        candidate_ids.discard(activity.user_id)

        if activity.type == Activity.ASSIGNED:
            # Only notify the assignee, and only if they are in the candidate set.
            recipient_ids = candidate_ids & set((activity.data['assignee'],))
        elif activity.type == Activity.NOTE:
            recipient_ids = candidate_ids - set(
                UserOption.objects.filter(
                    user__in=candidate_ids,
                    key='subscribe_notes',
                    value=u'0',
                ).values_list('user', flat=True)
            )
        else:
            recipient_ids = candidate_ids

        if not recipient_ids:
            return

        project = activity.project
        org = project.organization
        group = activity.group

        headers = {}

        context = {
            'data': activity.data,
            'author': activity.user,
            'project': project,
            'project_link': absolute_uri(reverse('sentry-stream', kwargs={
                'organization_slug': org.slug,
                'project_id': project.slug,
            })),
        }

        if group:
            group_link = absolute_uri('/{}/{}/group/{}/'.format(org.slug, project.slug, group.id))
            activity_link = '{}activity/'.format(group_link)

            headers.update({
                'X-Sentry-Reply-To': group_id_to_email(group.id),
            })

            context.update({
                'group': group,
                'link': group_link,
                'activity_link': activity_link,
            })

        # TODO(dcramer): abstract each activity email into its own helper class
        if activity.type == Activity.RELEASE:
            context.update({
                'release': Release.objects.get(
                    version=activity.data['version'],
                    project=project,
                ),
                'release_link': absolute_uri(reverse('sentry-release-details', kwargs={
                    'organization_slug': org.slug,
                    'project_id': project.slug,
                    'version': activity.data['version'],
                })),
            })

        template_name = activity.get_type_display()

        # TODO: Everything below should instead use `_send_mail` for consistency.
        subject_prefix = project.get_option('subject_prefix', settings.EMAIL_SUBJECT_PREFIX)
        if subject_prefix:
            subject_prefix = subject_prefix.rstrip() + ' '

        if group:
            subject = '%s%s' % (subject_prefix, group.get_email_subject())
        elif activity.type == Activity.RELEASE:
            subject = '%sRelease %s' % (subject_prefix, activity.data['version'])
        else:
            raise NotImplementedError

        msg = MessageBuilder(
            subject=subject,
            context=context,
            template='sentry/emails/activity/{}.txt'.format(template_name),
            html_template='sentry/emails/activity/{}.html'.format(template_name),
            headers=headers,
            reference=activity,
            reply_reference=group,
        )
        msg.add_users(recipient_ids, project=project)
        msg.send()
Exemple #23
0
 def setUp(self):
     self.address = ('0.0.0.0', 0)
     self.server = SentrySMTPServer(*self.address)
     self.mailto = group_id_to_email(self.group.pk)
     self.event  # side effect of generating an event
Exemple #24
0
    def notify_about_activity(self, activity):
        if activity.type not in (Activity.NOTE, Activity.ASSIGNED, Activity.RELEASE):
            return

        candidate_ids = set(self.get_send_to(activity.project))

        # Never send a notification to the user that performed the action.
        candidate_ids.discard(activity.user_id)

        if activity.type == Activity.ASSIGNED:
            # Only notify the assignee, and only if they are in the candidate set.
            recipient_ids = candidate_ids & set(map(int, (activity.data["assignee"],)))
        elif activity.type == Activity.NOTE:
            recipient_ids = candidate_ids - set(
                UserOption.objects.filter(user__in=candidate_ids, key="subscribe_notes", value=u"0").values_list(
                    "user", flat=True
                )
            )
        else:
            recipient_ids = candidate_ids

        if not recipient_ids:
            return

        project = activity.project
        org = project.organization
        group = activity.group

        headers = {}

        context = {
            "data": activity.data,
            "author": activity.user,
            "project": project,
            "project_link": absolute_uri(
                reverse("sentry-stream", kwargs={"organization_slug": org.slug, "project_id": project.slug})
            ),
        }

        if group:
            group_link = absolute_uri("/{}/{}/issues/{}/".format(org.slug, project.slug, group.id))
            activity_link = "{}activity/".format(group_link)

            headers.update({"X-Sentry-Reply-To": group_id_to_email(group.id)})

            context.update({"group": group, "link": group_link, "activity_link": activity_link})

        # TODO(dcramer): abstract each activity email into its own helper class
        if activity.type == Activity.RELEASE:
            context.update(
                {
                    "release": Release.objects.get(version=activity.data["version"], project=project),
                    "release_link": absolute_uri(
                        "/{}/{}/releases/{}/".format(org.slug, project.slug, activity.data["version"])
                    ),
                }
            )

        template_name = activity.get_type_display()

        if group:
            subject = group.get_email_subject()
        elif activity.type == Activity.RELEASE:
            subject = "Release %s" % activity.data["version"]
        else:
            raise NotImplementedError

        self._send_mail(
            project=project,
            send_to=recipient_ids,
            subject=subject,
            context=context,
            template="sentry/emails/activity/{}.txt".format(template_name),
            html_template="sentry/emails/activity/{}.html".format(template_name),
            headers=headers,
            reference=activity,
            reply_reference=group,
        )
Exemple #25
0
    def notify(self, notification):
        from sentry.models import Commit, Release

        event = notification.event

        group = event.group
        project = group.project
        org = group.organization

        subject = event.get_email_subject()

        link = group.get_absolute_url()

        template = 'sentry/emails/error.txt'
        html_template = 'sentry/emails/error.html'

        rules = []
        for rule in notification.rules:
            rule_link = '/%s/%s/settings/alerts/rules/%s/' % (
                org.slug, project.slug, rule.id)

            rules.append((rule.label, rule_link))

        enhanced_privacy = org.flags.enhanced_privacy

        # lets identify possibly suspect commits and owners
        commits = {}
        if features.has('organizations:suggested-commits', org):
            try:
                committers = get_event_file_committers(project, event)
            except (Commit.DoesNotExist, Release.DoesNotExist):
                pass
            except Exception as exc:
                logging.exception(six.text_type(exc))
            else:
                for committer in committers:
                    for commit in committer['commits']:
                        if commit['id'] not in commits:
                            commit_data = commit.copy()
                            commit_data['shortId'] = commit_data['id'][:7]
                            commit_data['author'] = committer['author']
                            commit_data['subject'] = commit_data[
                                'message'].split('\n', 1)[0]
                            commits[commit['id']] = commit_data

        context = {
            'project_label':
            project.get_full_name(),
            'group':
            group,
            'event':
            event,
            'link':
            link,
            'rules':
            rules,
            'enhanced_privacy':
            enhanced_privacy,
            'commits':
            sorted(commits.values(), key=lambda x: x['score'], reverse=True),
        }

        # if the organization has enabled enhanced privacy controls we dont send
        # data which may show PII or source code
        if not enhanced_privacy:
            interface_list = []
            for interface in six.itervalues(event.interfaces):
                body = interface.to_email_html(event)
                if not body:
                    continue
                text_body = interface.to_string(event)
                interface_list.append(
                    (interface.get_title(), mark_safe(body), text_body))

            context.update({
                'tags': event.get_tags(),
                'interfaces': interface_list,
            })

        headers = {
            'X-Sentry-Logger': group.logger,
            'X-Sentry-Logger-Level': group.get_level_display(),
            'X-Sentry-Project': project.slug,
            'X-Sentry-Reply-To': group_id_to_email(group.id),
        }

        for user_id in self.get_send_to(project=project, event=event):
            self.add_unsubscribe_link(context, user_id, project)
            self._send_mail(
                subject=subject,
                template=template,
                html_template=html_template,
                project=project,
                reference=group,
                headers=headers,
                type='notify.error',
                context=context,
                send_to=[user_id],
            )
Exemple #26
0
    def notify(self,
               notification,
               target_type,
               target_identifier=None,
               **kwargs):
        metrics.incr("mail_adapter.notify")
        event = notification.event
        environment = event.get_tag("environment")
        group = event.group
        project = group.project
        org = group.organization
        logger.info(
            "mail.adapter.notify",
            extra={
                "target_type": target_type.value,
                "target_identifier": target_identifier,
                "group": group.id,
                "project_id": project.id,
            },
        )

        subject = event.get_email_subject()

        query_params = {"referrer": "alert_email"}
        if environment:
            query_params["environment"] = environment
        link = group.get_absolute_url(params=query_params)

        template = "sentry/emails/error.txt"
        html_template = "sentry/emails/error.html"

        rules = []
        for rule in notification.rules:
            rule_link = "/settings/%s/projects/%s/alerts/rules/%s/" % (
                org.slug,
                project.slug,
                rule.id,
            )

            rules.append((rule.label, rule_link))

        enhanced_privacy = org.flags.enhanced_privacy

        # lets identify possibly suspect commits and owners
        commits = {}
        try:
            committers = get_serialized_event_file_committers(project, event)
        except (Commit.DoesNotExist, Release.DoesNotExist):
            pass
        except Exception as exc:
            logging.exception(six.text_type(exc))
        else:
            for committer in committers:
                for commit in committer["commits"]:
                    if commit["id"] not in commits:
                        commit_data = commit.copy()
                        commit_data["shortId"] = commit_data["id"][:7]
                        commit_data["author"] = committer["author"]
                        commit_data["subject"] = commit_data["message"].split(
                            "\n", 1)[0]
                        commits[commit["id"]] = commit_data

        project_plugins = plugins.for_project(project, version=1)
        organization_integrations = Integration.objects.filter(
            organizations=org).first()
        has_integrations = bool(project_plugins or organization_integrations)

        context = {
            "project_label":
            project.get_full_name(),
            "group":
            group,
            "event":
            event,
            "link":
            link,
            "rules":
            rules,
            "has_integrations":
            has_integrations,
            "enhanced_privacy":
            enhanced_privacy,
            "commits":
            sorted(commits.values(), key=lambda x: x["score"], reverse=True),
            "environment":
            environment,
        }

        # if the organization has enabled enhanced privacy controls we dont send
        # data which may show PII or source code
        if not enhanced_privacy:
            interface_list = []
            for interface in six.itervalues(event.interfaces):
                body = interface.to_email_html(event)
                if not body:
                    continue
                text_body = interface.to_string(event)
                interface_list.append(
                    (interface.get_title(), mark_safe(body), text_body))

            context.update({"tags": event.tags, "interfaces": interface_list})

        headers = {
            "X-Sentry-Logger": group.logger,
            "X-Sentry-Logger-Level": group.get_level_display(),
            "X-Sentry-Project": project.slug,
            "X-Sentry-Reply-To": group_id_to_email(group.id),
        }

        for user_id in self.get_send_to(
                project=project,
                target_type=target_type,
                target_identifier=target_identifier,
                event=event,
        ):
            logger.info(
                "mail.adapter.notify.mail_user",
                extra={
                    "target_type": target_type,
                    "target_identifier": target_identifier,
                    "group": group.id,
                    "project_id": project.id,
                    "user_id": user_id,
                },
            )

            self.add_unsubscribe_link(context, user_id, project, "alert_email")
            self._send_mail(
                subject=subject,
                template=template,
                html_template=html_template,
                project=project,
                reference=group,
                headers=headers,
                type="notify.error",
                context=context,
                send_to=[user_id],
            )
Exemple #27
0
    def notify_about_activity(self, activity):
        if activity.type not in (Activity.NOTE, Activity.ASSIGNED, Activity.RELEASE):
            return

        candidate_ids = set(self.get_send_to(activity.project))

        # Never send a notification to the user that performed the action.
        candidate_ids.discard(activity.user_id)

        if activity.type == Activity.ASSIGNED:
            # Only notify the assignee, and only if they are in the candidate set.
            recipient_ids = candidate_ids & set((activity.data['assignee'],))
        elif activity.type == Activity.NOTE:
            recipient_ids = candidate_ids - set(
                UserOption.objects.filter(
                    user__in=candidate_ids,
                    key='subscribe_notes',
                    value=u'0',
                ).values_list('user', flat=True)
            )
        else:
            recipient_ids = candidate_ids

        if not recipient_ids:
            return

        project = activity.project
        org = project.organization
        group = activity.group

        headers = {}

        context = {
            'data': activity.data,
            'author': activity.user,
            'project': project,
            'project_link': absolute_uri(reverse('sentry-stream', kwargs={
                'organization_slug': org.slug,
                'project_id': project.slug,
            })),
        }

        if group:
            group_link = absolute_uri('/{}/{}/group/{}/'.format(org.slug, project.slug, group.id))
            activity_link = '{}activity/'.format(group_link)

            headers.update({
                'X-Sentry-Reply-To': group_id_to_email(group.id),
            })

            context.update({
                'group': group,
                'link': group_link,
                'activity_link': activity_link,
            })

        # TODO(dcramer): abstract each activity email into its own helper class
        if activity.type == Activity.RELEASE:
            context.update({
                'release': Release.objects.get(
                    version=activity.data['version'],
                    project=project,
                ),
                'release_link': absolute_uri(reverse('sentry-release-details', kwargs={
                    'organization_slug': org.slug,
                    'project_id': project.slug,
                    'version': activity.data['version'],
                })),
            })

        template_name = activity.get_type_display()

        # TODO: Everything below should instead use `_send_mail` for consistency.
        subject_prefix = project.get_option('subject_prefix', settings.EMAIL_SUBJECT_PREFIX)
        if subject_prefix:
            subject_prefix = subject_prefix.rstrip() + ' '

        if group:
            subject = '%s%s' % (subject_prefix, group.get_email_subject())
        elif activity.type == Activity.RELEASE:
            subject = '%sRelease %s' % (subject_prefix, activity.data['version'])
        else:
            raise NotImplementedError

        msg = MessageBuilder(
            subject=subject,
            context=context,
            template='sentry/emails/activity/{}.txt'.format(template_name),
            html_template='sentry/emails/activity/{}.html'.format(template_name),
            headers=headers,
            reference=activity,
            reply_reference=group,
        )
        msg.add_users(recipient_ids, project=project)
        msg.send()
 def setUp(self):
     super(TestMailgunInboundWebhookView, self).setUp()
     self.event = self.create_event(event_id='a' * 32)
     self.mailto = group_id_to_email(self.group.pk)
 def setUp(self):
     super(TestMailgunInboundWebhookView, self).setUp()
     self.event = self.create_event(event_id='a' * 32)
     self.mailto = group_id_to_email(self.group.pk)
Exemple #30
0
 def setUp(self):
     super().setUp()
     self.event = self.store_event(data={"event_id": "a" * 32},
                                   project_id=self.project.id)
     self.mailto = group_id_to_email(self.group.pk)
Exemple #31
0
    def notify(self, notification):
        from sentry.models import Commit, Release

        event = notification.event

        environment = event.get_tag('environment')

        group = event.group
        project = group.project
        org = group.organization

        subject = event.get_email_subject()

        link = group.get_absolute_url()

        if environment:
            link = link + '?' + urlencode({'environment': environment})

        template = 'sentry/emails/error.txt'
        html_template = 'sentry/emails/error.html'

        rules = []
        for rule in notification.rules:
            rule_link = '/%s/%s/settings/alerts/rules/%s/' % (org.slug, project.slug, rule.id)

            rules.append((rule.label, rule_link))

        enhanced_privacy = org.flags.enhanced_privacy

        # lets identify possibly suspect commits and owners
        commits = {}
        if features.has('organizations:suggested-commits', org):
            try:
                committers = get_event_file_committers(project, event)
            except (Commit.DoesNotExist, Release.DoesNotExist):
                pass
            except Exception as exc:
                logging.exception(six.text_type(exc))
            else:
                for committer in committers:
                    for commit in committer['commits']:
                        if commit['id'] not in commits:
                            commit_data = commit.copy()
                            commit_data['shortId'] = commit_data['id'][:7]
                            commit_data['author'] = committer['author']
                            commit_data['subject'] = commit_data['message'].split('\n', 1)[0]
                            commits[commit['id']] = commit_data

        context = {
            'project_label': project.get_full_name(),
            'group': group,
            'event': event,
            'link': link,
            'rules': rules,
            'enhanced_privacy': enhanced_privacy,
            'commits': sorted(commits.values(), key=lambda x: x['score'], reverse=True),
            'environment': environment
        }

        # if the organization has enabled enhanced privacy controls we dont send
        # data which may show PII or source code
        if not enhanced_privacy:
            interface_list = []
            for interface in six.itervalues(event.interfaces):
                body = interface.to_email_html(event)
                if not body:
                    continue
                text_body = interface.to_string(event)
                interface_list.append((interface.get_title(), mark_safe(body), text_body))

            context.update({
                'tags': event.get_tags(),
                'interfaces': interface_list,
            })

        headers = {
            'X-Sentry-Logger': group.logger,
            'X-Sentry-Logger-Level': group.get_level_display(),
            'X-Sentry-Project': project.slug,
            'X-Sentry-Reply-To': group_id_to_email(group.id),
        }

        for user_id in self.get_send_to(project=project, event=event):
            self.add_unsubscribe_link(context, user_id, project)
            self._send_mail(
                subject=subject,
                template=template,
                html_template=html_template,
                project=project,
                reference=group,
                headers=headers,
                type='notify.error',
                context=context,
                send_to=[user_id],
            )
Exemple #32
0
    def send_notification(self):
        from sentry.models import User, UserOption
        from sentry.utils.email import MessageBuilder, group_id_to_email

        if self.type != Activity.NOTE or not self.group:
            return

        # TODO(dcramer): some of this logic is duplicated in NotificationPlugin
        # fetch access group members
        user_id_list = set(
            User.objects.filter(
                accessgroup__projects=self.project,
                is_active=True
            ).exclude(
                id=self.user_id,
            ).values_list('id', flat=True)
        )

        if self.project.team:
            # fetch team members
            user_id_list |= set(
                u_id for u_id in self.project.team.member_set.filter(
                    user__is_active=True,
                ).exclude(
                    user__id=self.user_id,
                ).values_list('user', flat=True)
            )

        if not user_id_list:
            return

        disabled = set(UserOption.objects.filter(
            user__in=user_id_list,
            key='subscribe_comments',
            value='0',
        ).values_list('user', flat=True))

        send_to = [
            u_id for u_id in user_id_list if u_id not in disabled
        ]

        if not send_to:
            return

        author = self.user.first_name or self.user.username

        subject = '[%s] %s: %s' % (
            self.project.name,
            author,
            self.data['text'].splitlines()[0][:64])

        context = {
            'text': self.data['text'],
            'author': author,
            'group': self.group,
            'link': self.group.get_absolute_url(),
        }

        headers = {
            'X-Sentry-Reply-To': group_id_to_email(self.group.pk),
        }

        msg = MessageBuilder(
            subject=subject,
            context=context,
            template='sentry/emails/new_note.txt',
            html_template='sentry/emails/new_note.html',
            headers=headers,
        )
        msg.add_users(send_to, project=self.project)

        try:
            msg.send()
        except Exception, e:
            logger = logging.getLogger('sentry.mail.errors')
            logger.exception(e)
Exemple #33
0
    def send_notification(self):
        from sentry.models import User, UserOption, ProjectOption
        from sentry.utils.email import MessageBuilder, group_id_to_email

        if self.type != Activity.NOTE or not self.group:
            return

        # TODO(dcramer): some of this logic is duplicated in NotificationPlugin
        # fetch access group members
        user_id_list = set(
            User.objects.filter(
                accessgroup__projects=self.project,
                is_active=True
            ).exclude(
                id=self.user_id,
            ).values_list('id', flat=True)
        )

        if self.project.team:
            # fetch team members
            user_id_list |= set(
                u_id for u_id in self.project.team.member_set.filter(
                    user__is_active=True,
                ).exclude(
                    user__id=self.user_id,
                ).values_list('user', flat=True)
            )

        if not user_id_list:
            return

        disabled = set(UserOption.objects.filter(
            user__in=user_id_list,
            key='subscribe_notes',
            value=u'0',
        ).values_list('user', flat=True))

        send_to = filter(lambda u_id: u_id not in disabled, user_id_list)

        if not send_to:
            return

        author = self.user.first_name or self.user.username

        subject_prefix = ProjectOption.objects.get_value(
            self.project, 'subject_prefix', settings.EMAIL_SUBJECT_PREFIX)
        if subject_prefix:
            subject_prefix = subject_prefix.rstrip() + ' '

        subject = '%s%s' % (subject_prefix, self.event.get_email_subject())

        context = {
            'text': self.data['text'],
            'author': author,
            'group': self.group,
            'link': self.group.get_absolute_url(),
        }

        headers = {
            'X-Sentry-Reply-To': group_id_to_email(self.group.pk),
        }

        msg = MessageBuilder(
            subject=subject,
            context=context,
            template='sentry/emails/new_note.txt',
            html_template='sentry/emails/new_note.html',
            headers=headers,
            reference=self,
            reply_reference=self.group,
        )
        msg.add_users(send_to, project=self.project)

        try:
            msg.send()
        except Exception as e:
            logger = logging.getLogger('sentry.mail.errors')
            logger.exception(e)
Exemple #34
0
    def send_notification(self):
        from sentry.models import Release
        from sentry.utils.email import MessageBuilder, group_id_to_email

        if self.type not in (Activity.NOTE, Activity.ASSIGNED, Activity.RELEASE):
            return

        send_to = self.get_recipients()

        if not send_to:
            return

        project = self.project
        org = self.project.organization

        if self.user:
            author = self.user.first_name or self.user.username
        else:
            author = None

        subject_prefix = self.project.get_option(
            'subject_prefix', settings.EMAIL_SUBJECT_PREFIX)
        if subject_prefix:
            subject_prefix = subject_prefix.rstrip() + ' '

        if self.group:
            subject = '%s%s' % (subject_prefix, self.group.get_email_subject())
        elif self.type == Activity.RELEASE:
            subject = '%sRelease %s' % (subject_prefix, self.data['version'])
        else:
            raise NotImplementedError

        headers = {}

        context = {
            'data': self.data,
            'author': author,
            'project': self.project,
            'project_link': absolute_uri(reverse('sentry-stream', kwargs={
                'organization_slug': org.slug,
                'project_id': project.slug,
            })),
        }

        if self.group:
            headers.update({
                'X-Sentry-Reply-To': group_id_to_email(self.group.id),
            })

            context.update({
                'group': self.group,
                'link': self.group.get_absolute_url(),
            })

        # TODO(dcramer): abstract each activity email into its own helper class
        if self.type == Activity.RELEASE:
            context.update({
                'release': Release.objects.get(
                    version=self.data['version'],
                    project=project,
                ),
                'release_link': absolute_uri(reverse('sentry-release-details', kwargs={
                    'organization_slug': org.slug,
                    'project_id': project.slug,
                    'version': self.data['version'],
                })),
            })

        template_name = self.get_type_display()

        msg = MessageBuilder(
            subject=subject,
            context=context,
            template='sentry/emails/activity/{}.txt'.format(template_name),
            html_template='sentry/emails/activity/{}.html'.format(template_name),
            headers=headers,
            reference=self,
            reply_reference=self.group,
        )
        msg.add_users(send_to, project=self.project)
        msg.send_async()
Exemple #35
0
    def notify(self, notification):
        event = notification.event
        group = event.group
        project = group.project
        org = group.organization

        subject = event.get_email_subject()

        link = group.get_absolute_url()

        template = 'sentry/emails/error.txt'
        html_template = 'sentry/emails/error.html'

        rules = []
        for rule in notification.rules:
            rule_link = reverse('sentry-edit-project-rule', args=[
                org.slug, project.slug, rule.id
            ])
            rules.append((rule.label, rule_link))

        enhanced_privacy = org.flags.enhanced_privacy

        context = {
            'project_label': project.get_full_name(),
            'group': group,
            'event': event,
            'link': link,
            'rules': rules,
            'enhanced_privacy': enhanced_privacy,
        }

        # if the organization has enabled enhanced privacy controls we dont send
        # data which may show PII or source code
        if not enhanced_privacy:
            interface_list = []
            for interface in six.itervalues(event.interfaces):
                body = interface.to_email_html(event)
                if not body:
                    continue
                text_body = interface.to_string(event)
                interface_list.append(
                    (interface.get_title(), mark_safe(body), text_body)
                )

            context.update({
                'tags': event.get_tags(),
                'interfaces': interface_list,
            })

        headers = {
            'X-Sentry-Logger': group.logger,
            'X-Sentry-Logger-Level': group.get_level_display(),
            'X-Sentry-Team': project.team.name,
            'X-Sentry-Project': project.name,
            'X-Sentry-Reply-To': group_id_to_email(group.id),
        }

        for user_id in self.get_send_to(project):
            self.add_unsubscribe_link(context, user_id, project)
            self._send_mail(
                subject=subject,
                template=template,
                html_template=html_template,
                project=project,
                reference=group,
                headers=headers,
                type='notify.error',
                context=context,
                send_to=[user_id],
            )
Exemple #36
0
 def setUp(self):
     super(TestMailgunInboundWebhookView, self).setUp()
     self.event = self.store_event(data={"event_id": "a" * 32},
                                   project_id=self.project.id)
     self.mailto = group_id_to_email(self.group.pk)