Esempio n. 1
0
    def to_internal_value(self, data):
        if not data:
            return None

        try:
            actor = ActorTuple.from_actor_identifier(data)
        except Exception:
            raise serializers.ValidationError(
                "Could not parse actor. Format should be `type:id` where type is `team` or `user`."
            )
        try:
            obj = actor.resolve()
        except (Team.DoesNotExist, User.DoesNotExist):
            raise serializers.ValidationError(
                f"{actor.type.__name__} does not exist")

        if actor.type == Team:
            if obj.organization != self.context["organization"]:
                raise serializers.ValidationError(
                    "Team is not a member of this organization")
        elif actor.type == User:
            if not OrganizationMember.objects.filter(
                    organization=self.context["organization"],
                    user=obj).exists():
                raise serializers.ValidationError(
                    "User is not a member of this organization")
        return actor
Esempio n. 2
0
    def to_internal_value(self, data):
        if not data:
            return None

        try:
            return ActorTuple.from_actor_identifier(data)
        except Exception:
            raise serializers.ValidationError("Unknown actor input")
Esempio n. 3
0
 def validate_owner(self, owner):
     # owner should be team:id or user:id
     try:
         actor = ActorTuple.from_actor_identifier(owner)
     except serializers.ValidationError:
         raise serializers.ValidationError(
             "Could not parse owner. Format should be `type:id` where type is `team` or `user`."
         )
     try:
         if actor.resolve():
             return actor
     except (User.DoesNotExist, Team.DoesNotExist):
         raise serializers.ValidationError(
             "Could not resolve owner to existing team or user.")
Esempio n. 4
0
    def test_transfer_to_organization_alert_rules(self):
        from_org = self.create_organization()
        from_user = self.create_user()
        self.create_member(user=from_user,
                           role="member",
                           organization=from_org)
        team = self.create_team(organization=from_org)
        to_org = self.create_organization()
        to_team = self.create_team(organization=to_org)
        to_user = self.create_user()
        self.create_member(user=to_user, role="member", organization=to_org)

        project = self.create_project(teams=[team])

        # should lose their owners
        alert_rule = self.create_alert_rule(
            organization=self.organization,
            projects=[project],
            owner=ActorTuple.from_actor_identifier(f"team:{team.id}"),
        )
        rule1 = Rule.objects.create(label="another test rule",
                                    project=project,
                                    owner=team.actor)
        rule2 = Rule.objects.create(label="rule4",
                                    project=project,
                                    owner=from_user.actor)

        # should keep their owners
        rule3 = Rule.objects.create(label="rule2",
                                    project=project,
                                    owner=to_team.actor)
        rule4 = Rule.objects.create(label="rule3",
                                    project=project,
                                    owner=to_user.actor)

        project.transfer_to(organization=to_org)

        alert_rule.refresh_from_db()
        rule1.refresh_from_db()
        rule2.refresh_from_db()
        rule3.refresh_from_db()
        rule4.refresh_from_db()
        assert alert_rule.organization_id == to_org.id
        assert alert_rule.owner is None
        assert rule1.owner is None
        assert rule2.owner is None

        assert rule3.owner is not None
        assert rule4.owner is not None
Esempio n. 5
0
def build_assigned_text(identity: Identity, assignee: str):
    actor = ActorTuple.from_actor_identifier(assignee)

    try:
        assigned_actor = actor.resolve()
    except actor.type.DoesNotExist:
        return

    if actor.type == Team:
        assignee_text = f"#{assigned_actor.slug}"
    elif actor.type == User:
        try:
            assignee_ident = Identity.objects.get(
                user=assigned_actor, idp__type="slack", idp__external_id=identity.idp.external_id
            )
            assignee_text = f"<@{assignee_ident.external_id}>"
        except Identity.DoesNotExist:
            assignee_text = assigned_actor.get_display_name()
    else:
        raise NotImplementedError

    return f"*Issue assigned to {assignee_text} by <@{identity.external_id}>*"
Esempio n. 6
0
    def assigned_actor(self):
        from sentry.models import ActorTuple

        return ActorTuple.from_actor_identifier(self.assigned_actor_id())
Esempio n. 7
0
    def owner(self):
        from sentry.models import ActorTuple

        return ActorTuple.from_actor_identifier(self.owner_id())
    def test_simple(self):
        project1 = self.create_project(
            teams=[self.team], slug="foo"
        )  # This project will return counts for this team
        user_owned_rule = self.create_alert_rule(
            organization=self.organization,
            projects=[project1],
            name="user owned rule",
            query="",
            aggregate="count()",
            time_window=1,
            threshold_type=AlertRuleThresholdType.ABOVE,
            resolve_threshold=10,
            threshold_period=1,
            owner=ActorTuple.from_actor_identifier(self.user.id),
        )
        user_owned_incident = self.create_incident(status=20, alert_rule=user_owned_rule)
        activities = []
        for i in range(1, 9):
            activities.append(
                IncidentActivity(
                    incident=user_owned_incident,
                    type=IncidentActivityType.CREATED.value,
                    value=IncidentStatus.OPEN,
                    date_added=before_now(days=i),
                )
            )
        IncidentActivity.objects.bulk_create(activities)

        self.login_as(user=self.user)
        response = self.get_success_response(self.team.organization.slug, self.team.slug)
        assert len(response.data) == 90
        for i in range(1, 9):
            assert (
                response.data[
                    str(
                        before_now(days=i)
                        .replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=timezone.utc)
                        .isoformat()
                    )
                ]
                == 1
            )

        for i in range(10, 90):
            assert (
                response.data[
                    str(
                        before_now(days=i)
                        .replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=timezone.utc)
                        .isoformat()
                    )
                ]
                == 0
            )

        response = self.get_success_response(
            self.team.organization.slug, self.team.slug, statsPeriod="7d"
        )
        assert len(response.data) == 7
        assert (
            response.data[
                str(
                    before_now(days=0)
                    .replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=timezone.utc)
                    .isoformat()
                )
            ]
            == 0
        )
        for i in range(1, 6):
            assert (
                response.data[
                    str(
                        before_now(days=i)
                        .replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=timezone.utc)
                        .isoformat()
                    )
                ]
                == 1
            )
    def test_not_as_simple(self):
        team_with_user = self.create_team(
            organization=self.organization, name="Lonely Team", members=[self.user]
        )

        project1 = self.create_project(
            teams=[self.team], slug="foo"
        )  # This project will return counts for this team
        project2 = self.create_project(
            # teams=[team_with_user], slug="bar"
            teams=[team_with_user],
            slug="bar",
        )  # but not this project, cause this team isn't on it (but the user is)

        user_owned_rule = self.create_alert_rule(
            organization=self.organization,
            projects=[project2],
            name="user owned rule",
            query="",
            aggregate="count()",
            time_window=1,
            threshold_type=AlertRuleThresholdType.ABOVE,
            resolve_threshold=10,
            threshold_period=1,
            owner=ActorTuple.from_actor_identifier(self.user.id),
        )
        user_owned_incident = self.create_incident(
            projects=[project2], status=20, alert_rule=user_owned_rule
        )
        team_owned_rule = self.create_alert_rule(
            organization=self.organization,
            projects=[project1],
            name="team owned rule",
            query="",
            aggregate="count()",
            time_window=1,
            threshold_type=AlertRuleThresholdType.ABOVE,
            resolve_threshold=10,
            threshold_period=1,
            owner=ActorTuple.from_actor_identifier(f"team:{self.team.id}"),
        )
        team_owned_incident = self.create_incident(
            projects=[project1], status=20, alert_rule=team_owned_rule
        )
        IncidentActivity.objects.create(
            incident=user_owned_incident,
            type=IncidentActivityType.CREATED.value,
            value=IncidentStatus.OPEN,
        )
        IncidentActivity.objects.create(
            incident=team_owned_incident,
            type=IncidentActivityType.CREATED.value,
            value=IncidentStatus.OPEN,
            date_added=before_now(days=2),
        )

        self.login_as(user=self.user)
        response = self.get_success_response(self.team.organization.slug, self.team.slug)
        assert len(response.data) == 90
        assert (
            response.data[
                str(
                    before_now(days=2)
                    .replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=timezone.utc)
                    .isoformat()
                )
            ]
            == 1
        )
        # only getting the team owned incident, because the user owned incident is for another project that the team isn't on
        for i in range(0, 90):
            if i != 2:
                assert (
                    response.data[
                        str(
                            before_now(days=i)
                            .replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=timezone.utc)
                            .isoformat()
                        )
                    ]
                    == 0
                )
Esempio n. 10
0
    def test(self):
        project1 = self.create_project(teams=[self.team], slug="foo")
        user_owned_rule = self.create_alert_rule(
            organization=self.organization,
            projects=[project1],
            name="user owned rule",
            owner=ActorTuple.from_actor_identifier(self.user.id),
        )

        user_owned_incident = self.create_incident(status=20, alert_rule=user_owned_rule)
        activities = []
        for i in range(0, 8):
            activities.append(
                IncidentActivity(
                    incident=user_owned_incident,
                    type=IncidentActivityType.CREATED.value,
                    value=IncidentStatus.OPEN,
                    date_added=before_now(weeks=i),
                )
            )
        team_owned_rule = self.create_alert_rule(
            organization=self.organization,
            projects=[project1],
            name="team owned rule",
            owner=ActorTuple.from_actor_identifier(f"team:{self.team.id}"),
        )
        team_owned_incident = self.create_incident(status=20, alert_rule=team_owned_rule)
        activities.append(
            IncidentActivity(
                incident=team_owned_incident,
                type=IncidentActivityType.CREATED.value,
                value=IncidentStatus.OPEN,
                date_added=before_now(weeks=0),
            )
        )

        for i in range(0, 10):
            activities.append(
                IncidentActivity(
                    incident=team_owned_incident,
                    type=IncidentActivityType.CREATED.value,
                    value=IncidentStatus.OPEN,
                    date_added=before_now(weeks=i),
                )
            )
        IncidentActivity.objects.bulk_create(activities)

        self.login_as(user=self.user)
        response = self.get_success_response(
            self.team.organization.slug, self.team.slug, statsPeriod="8w"
        )
        assert [
            {"id": row["id"], "totalThisWeek": row["totalThisWeek"], "weeklyAvg": row["weeklyAvg"]}
            for row in response.data
        ] == [
            {"id": str(team_owned_rule.id), "totalThisWeek": 2, "weeklyAvg": 1.375},
            {"id": str(user_owned_rule.id), "totalThisWeek": 1, "weeklyAvg": 1},
        ]

        response = self.get_success_response(
            self.team.organization.slug, self.team.slug, per_page=1, statsPeriod="10w"
        )
        assert [
            {"id": row["id"], "totalThisWeek": row["totalThisWeek"], "weeklyAvg": row["weeklyAvg"]}
            for row in response.data
        ] == [
            {"id": str(team_owned_rule.id), "totalThisWeek": 2, "weeklyAvg": 1.1},
        ]
        next_cursor = self.get_cursor_headers(response)[1]
        response = self.get_success_response(
            self.team.organization.slug,
            self.team.slug,
            per_page=1,
            cursor=next_cursor,
            statsPeriod="10w",
        )
        assert [
            {"id": row["id"], "totalThisWeek": row["totalThisWeek"], "weeklyAvg": row["weeklyAvg"]}
            for row in response.data
        ] == [
            {"id": str(user_owned_rule.id), "totalThisWeek": 1, "weeklyAvg": 0.8},
        ]