예제 #1
0
파일: mail.py 프로젝트: littlekign/sentry
    def get(self, request: Request) -> Response:
        org = Organization(id=1, slug="organization", name="My Company")
        project = Project(id=1, organization=org, slug="project", name="My Project")

        group = next(make_group_generator(get_random(request), project))

        data = dict(load_data("python"))
        data["message"] = group.message
        data.pop("logentry", None)

        event_manager = EventManager(data)
        event_manager.normalize()
        data = event_manager.get_data()
        event_type = get_event_type(data)

        event = eventstore.create_event(
            event_id="a" * 32, group_id=group.id, project_id=project.id, data=data.data
        )

        group.message = event.search_message
        group.data = {"type": event_type.key, "metadata": event_type.get_metadata(data)}

        activity = Activity(group=group, project=event.project, **self.get_activity(request, event))

        return render_to_response(
            "sentry/debug/mail/preview.html",
            context={
                "preview": ActivityMailPreview(request, activity),
                "format": request.GET.get("format"),
            },
        )
예제 #2
0
    def test_notify_users_does_email(self, mock_func):
        event_manager = EventManager({
            "message": "hello world",
            "level": "error"
        })
        event_manager.normalize()
        event_data = event_manager.get_data()
        event_type = get_event_type(event_data)
        event_data["type"] = event_type.key
        event_data["metadata"] = event_type.get_metadata(event_data)

        event = event_manager.save(self.project.id)
        group = event.group

        with self.tasks():
            AlertRuleNotification(Notification(event=event),
                                  ActionTargetType.ISSUE_OWNERS).send()

        assert mock_func.call_count == 1

        args, kwargs = mock_func.call_args
        notification = args[1]

        self.assertEquals(notification.project, self.project)
        self.assertEquals(notification.get_reference(), group)
        assert notification.get_subject() == "BAR-1 - hello world"
예제 #3
0
    def test_notify_users_does_email(self, mock_func):
        UserOption.objects.create(user=self.user,
                                  key="timezone",
                                  value="Europe/Vienna")
        event_manager = EventManager({
            "message": "hello world",
            "level": "error"
        })
        event_manager.normalize()
        event_data = event_manager.get_data()
        event_type = get_event_type(event_data)
        event_data["type"] = event_type.key
        event_data["metadata"] = event_type.get_metadata(event_data)

        event = event_manager.save(self.project.id)
        group = event.group

        with self.tasks():
            AlertRuleNotification(Notification(event=event),
                                  ActionTargetType.ISSUE_OWNERS).send()

        assert mock_func.call_count == 1

        args, kwargs = mock_func.call_args
        notification = args[1]

        assert notification.get_user_context(
            self.user, {})["timezone"] == pytz.timezone("Europe/Vienna")

        self.assertEquals(notification.project, self.project)
        self.assertEquals(notification.get_reference(), group)
        assert notification.get_subject() == "BAR-1 - hello world"
예제 #4
0
    def test_email_notification_is_not_sent_to_deleted_email(self, mock_func):
        """
        Test that ensures if we still have some stale emails in UserOption, then upon attempting
        to send an email notification to those emails, these stale `UserOption` instances are
        deleted
        """
        # Initial Creation
        user = self.create_user(email="*****@*****.**", is_active=True)
        self.create_member(user=user,
                           organization=self.organization,
                           teams=[self.team])

        UserOption.objects.create(user=user,
                                  key="mail:email",
                                  value="*****@*****.**",
                                  project=self.project)

        # New secondary email is created
        useremail = UserEmail.objects.create(user=user,
                                             email="*****@*****.**",
                                             is_verified=True)

        # Set secondary email to be primary
        user.email = useremail.email
        user.save()

        # Delete first email
        old_useremail = UserEmail.objects.get(email="*****@*****.**")
        old_useremail.delete()

        event_manager = EventManager({
            "message": "hello world",
            "level": "error"
        })
        event_manager.normalize()
        event_data = event_manager.get_data()
        event_type = get_event_type(event_data)
        event_data["type"] = event_type.key
        event_data["metadata"] = event_type.get_metadata(event_data)

        event = event_manager.save(self.project.id)

        with self.tasks():
            AlertRuleNotification(Notification(event=event),
                                  ActionTargetType.ISSUE_OWNERS).send()

        assert mock_func.call_count == 1

        args, kwargs = mock_func.call_args
        notification = args[1]

        user_ids = []
        for user in list(notification.get_participants().values())[0]:
            user_ids.append(user.id)
        assert "*****@*****.**" in get_email_addresses(user_ids,
                                                       self.project).values()
        assert not len(
            UserOption.objects.filter(key="mail:email", value="*****@*****.**"))
예제 #5
0
 def make_event_data(self, filename, url="http://example.com"):
     mgr = EventManager(
         {
             "tags": [("level", "error")],
             "stacktrace": {"frames": [{"lineno": 1, "filename": filename}]},
             "request": {"url": url},
         }
     )
     mgr.normalize()
     data = mgr.get_data()
     event_type = get_event_type(data)
     data["type"] = event_type.key
     data["metadata"] = event_type.get_metadata(data)
     return data
예제 #6
0
    def test_multiline_error(self, _send_mail):
        event_manager = EventManager({"message": "hello world\nfoo bar", "level": "error"})
        event_manager.normalize()
        event_data = event_manager.get_data()
        event_type = get_event_type(event_data)
        event_data["type"] = event_type.key
        event_data["metadata"] = event_type.get_metadata(event_data)

        event = event_manager.save(self.project.id)

        notification = Notification(event=event)

        with self.options({"system.url-prefix": "http://example.com"}):
            self.adapter.notify(notification, ActionTargetType.ISSUE_OWNERS)

        assert _send_mail.call_count == 1
        args, kwargs = _send_mail.call_args
        assert kwargs.get("subject") == "BAR-1 - hello world"
예제 #7
0
def _process_snuba_results(query_res, group: Group, id: int, user):
    event_ids = {
        row["latest_event_id"]: Event.generate_node_id(group.project_id,
                                                       row["latest_event_id"])
        for row in query_res
    }

    node_data = nodestore.get_multi(list(event_ids.values()))

    response = []

    for row in query_res:
        response_item = {
            "hash": row["new_materialized_hash"],
            "eventCount": row["event_count"],
        }
        event_id = row["latest_event_id"]
        event_data = node_data.get(event_ids[event_id], None)

        if event_data is not None:
            event = Event(group.project_id,
                          event_id,
                          group_id=group.id,
                          data=event_data)
            response_item["latestEvent"] = serialize(event, user,
                                                     EventSerializer())

            tree_label = get_path(
                event_data, "hierarchical_tree_labels", id) or get_path(
                    event_data, "hierarchical_tree_labels", -1)

            # Rough approximation of what happens with Group title
            event_type = get_event_type(event.data)
            metadata = dict(event.get_event_metadata())
            metadata["current_tree_label"] = tree_label
            # Force rendering of grouping tree labels irrespective of platform
            metadata["display_title_with_tree_label"] = True
            title = event_type.get_title(metadata)
            response_item["title"] = title or event.title
            response_item["metadata"] = metadata

        response.append(response_item)

    return response
예제 #8
0
    def test_multiline_error(self, mock_func):
        event_manager = EventManager({
            "message": "hello world\nfoo bar",
            "level": "error"
        })
        event_manager.normalize()
        event_data = event_manager.get_data()
        event_type = get_event_type(event_data)
        event_data["type"] = event_type.key
        event_data["metadata"] = event_type.get_metadata(event_data)

        event = event_manager.save(self.project.id)
        with self.tasks():
            AlertRuleNotification(Notification(event=event),
                                  ActionTargetType.ISSUE_OWNERS).send()

        assert mock_func.call_count == 1
        args, kwargs = mock_func.call_args
        notification = args[1]
        assert notification.get_subject() == "BAR-1 - hello world"
예제 #9
0
    def test_notify_users_does_email(self, _send_mail):
        event_manager = EventManager({"message": "hello world", "level": "error"})
        event_manager.normalize()
        event_data = event_manager.get_data()
        event_type = get_event_type(event_data)
        event_data["type"] = event_type.key
        event_data["metadata"] = event_type.get_metadata(event_data)

        event = event_manager.save(self.project.id)
        group = event.group

        notification = Notification(event=event)

        with self.options({"system.url-prefix": "http://example.com"}):
            self.adapter.notify(notification, ActionTargetType.ISSUE_OWNERS)

        assert _send_mail.call_count == 1
        args, kwargs = _send_mail.call_args
        self.assertEquals(kwargs.get("project"), self.project)
        self.assertEquals(kwargs.get("reference"), group)
        assert kwargs.get("subject") == "BAR-1 - hello world"
예제 #10
0
    def create_event(self, grouping_config=None):
        input = dict(self.data)

        config = FingerprintingRules.from_json({
            "rules":
            input.pop("_fingerprinting_rules"),
            "version":
            1
        })
        mgr = EventManager(data=input, grouping_config=grouping_config)
        mgr.normalize()
        data = mgr.get_data()

        data.setdefault("fingerprint", ["{{ default }}"])
        apply_server_fingerprinting(data, config)
        event_type = get_event_type(data)
        event_metadata = event_type.get_metadata(data)
        data.update(materialize_metadata(data, event_type, event_metadata))

        evt = eventstore.create_event(data=data)
        return config, evt
예제 #11
0
 def inner(data):
     mgr = EventManager(
         data={
             "expectstaple": data,
             "logentry": {"message": "XXX EXPECTSTAPLE MESSAGE NOT THROUGH RELAY XXX"},
         }
     )
     mgr.normalize()
     data = mgr.get_data()
     event_type = get_event_type(data)
     event_metadata = event_type.get_metadata(data)
     data.update(materialize_metadata(data, event_type, event_metadata))
     evt = eventstore.create_event(data=data)
     insta_snapshot(
         {
             "errors": evt.data.get("errors"),
             "to_json": evt.interfaces.get("expectstaple").to_json(),
             "metadata": evt.get_event_metadata(),
             "title": evt.title,
         }
     )
예제 #12
0
def alert(request):
    platform = request.GET.get("platform", "python")
    org = Organization(id=1, slug="example", name="Example")
    project = Project(id=1, slug="example", name="Example", organization=org)

    random = get_random(request)
    group = next(make_group_generator(random, project))

    data = dict(load_data(platform))
    data["message"] = group.message
    data["event_id"] = "44f1419e73884cd2b45c79918f4b6dc4"
    data.pop("logentry", None)
    data["environment"] = "prod"
    data["tags"] = [
        ("logger", "javascript"),
        ("environment", "prod"),
        ("level", "error"),
        ("device", "Other"),
    ]

    event_manager = EventManager(data)
    event_manager.normalize()
    data = event_manager.get_data()
    event = event_manager.save(project.id)
    # Prevent CI screenshot from constantly changing
    event.data["timestamp"] = 1504656000.0  # datetime(2017, 9, 6, 0, 0)
    event_type = get_event_type(event.data)

    group.message = event.search_message
    group.data = {
        "type": event_type.key,
        "metadata": event_type.get_metadata(data)
    }

    rule = Rule(id=1, label="An example rule")

    # XXX: this interface_list code needs to be the same as in
    #      src/sentry/mail/adapter.py
    interface_list = []
    for interface in event.interfaces.values():
        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))

    return MailPreview(
        html_template="sentry/emails/error.html",
        text_template="sentry/emails/error.txt",
        context={
            "rule":
            rule,
            "rules":
            get_rules([rule], org, project),
            "group":
            group,
            "event":
            event,
            "timezone":
            pytz.timezone("Europe/Vienna"),
            # http://testserver/organizations/example/issues/<issue-id>/?referrer=alert_email
            #       &alert_type=email&alert_timestamp=<ts>&alert_rule_id=1
            "link":
            get_group_settings_link(group, None, get_rules([rule], org,
                                                           project), 1337),
            "interfaces":
            interface_list,
            "tags":
            event.tags,
            "project_label":
            project.slug,
            "alert_status_page_enabled":
            features.has("organizations:alert-rule-status-page", org),
            "commits": [{
                # TODO(dcramer): change to use serializer
                "repository": {
                    "status": "active",
                    "name": "Example Repo",
                    "url": "https://github.com/example/example",
                    "dateCreated": "2018-02-28T23:39:22.402Z",
                    "provider": {
                        "id": "github",
                        "name": "GitHub"
                    },
                    "id": "1",
                },
                "score": 2,
                "subject": "feat: Do something to raven/base.py",
                "message":
                "feat: Do something to raven/base.py\naptent vivamus vehicula tempus volutpat hac tortor",
                "id": "1b17483ffc4a10609e7921ee21a8567bfe0ed006",
                "shortId": "1b17483",
                "author": {
                    "username":
                    "******",
                    "isManaged":
                    False,
                    "lastActive":
                    "2018-03-01T18:25:28.149Z",
                    "id":
                    "1",
                    "isActive":
                    True,
                    "has2fa":
                    False,
                    "name":
                    "*****@*****.**",
                    "avatarUrl":
                    "https://secure.gravatar.com/avatar/51567a4f786cd8a2c41c513b592de9f9?s=32&d=mm",
                    "dateJoined":
                    "2018-02-27T22:04:32.847Z",
                    "emails": [{
                        "is_verified": False,
                        "id": "1",
                        "email": "*****@*****.**"
                    }],
                    "avatar": {
                        "avatarUuid": None,
                        "avatarType": "letter_avatar"
                    },
                    "lastLogin":
                    "******",
                    "email":
                    "*****@*****.**",
                },
            }],
        },
    ).render(request)