Beispiel #1
0
    def get_owners(cls, project_id, data):
        """
        For a given project_id, and event data blob.
        We combine the schemas from IssueOwners and CodeOwners.

        If Everyone is returned, this means we implicitly are
        falling through our rules and everyone is responsible.

        If an empty list is returned, this means there are explicitly
        no owners.
        """
        from sentry.models import ProjectCodeOwners

        ownership = cls.get_ownership_cached(project_id)
        if not ownership:
            ownership = cls(project_id=project_id)

        codeowners = ProjectCodeOwners.get_codeowners_cached(project_id)
        ownership.schema = cls.get_combined_schema(ownership, codeowners)

        rules = cls._matching_ownership_rules(ownership, project_id, data)

        if not rules:
            return cls.Everyone if ownership.fallthrough else [], None

        owners = {o for rule in rules for o in rule.owners}
        owners_to_actors = resolve_actors(owners, project_id)
        ordered_actors = []
        for rule in rules:
            for o in rule.owners:
                if o in owners and owners_to_actors.get(o) is not None:
                    ordered_actors.append(owners_to_actors[o])
                    owners.remove(o)

        return ordered_actors, rules
 def test_basic(self):
     owners = [
         Owner("user", self.user.email),
         Owner("team", self.team.slug)
     ]
     assert resolve_actors(owners, self.project.id) == {
         owners[0]: ActorTuple(self.user.id, User),
         owners[1]: ActorTuple(self.team.id, Team),
     }
Beispiel #3
0
 def _find_actors(cls, project_id, rules, limit):
     """
     Get the last matching rule to take the most precedence.
     """
     owners = [owner for rule in rules for owner in rule.owners]
     owners.reverse()
     actors = {
         key: val
         for key, val in resolve_actors({owner for owner in owners}, project_id).items()
         if val
     }
     actors = [actors[owner] for owner in owners if owner in actors][:limit]
     return actors
Beispiel #4
0
    def get_owners(
        cls, project_id: int, data: Mapping[str, Any]
    ) -> Tuple[Union["Everyone", Sequence["ActorTuple"]],
               Optional[Sequence[Rule]]]:
        """
        For a given project_id, and event data blob.
        We combine the schemas from IssueOwners and CodeOwners.

        If there are no matching rules, check ProjectOwnership.fallthrough:
            If ProjectOwnership.fallthrough is enabled, return Everyone (all project members)
             - we implicitly are falling through our rules and everyone is responsible.
            If ProjectOwnership.fallthrough is disabled, return an empty list
             - there are explicitly no owners

        If there are matching rules, return the ordered actors.
            The order is determined by iterating through rules sequentially, evaluating
            CODEOWNERS (if present), followed by Ownership Rules
        """
        from sentry.models import ProjectCodeOwners

        ownership = cls.get_ownership_cached(project_id)
        if not ownership:
            ownership = cls(project_id=project_id)

        codeowners = ProjectCodeOwners.get_codeowners_cached(project_id)
        ownership.schema = cls.get_combined_schema(ownership, codeowners)

        rules = cls._matching_ownership_rules(ownership, project_id, data)

        if not rules:
            return cls.Everyone if ownership.fallthrough else [], None

        owners = {o for rule in rules for o in rule.owners}
        owners_to_actors = resolve_actors(owners, project_id)
        ordered_actors = []
        for rule in rules:
            for o in rule.owners:
                if o in owners and owners_to_actors.get(o) is not None:
                    ordered_actors.append(owners_to_actors[o])
                    owners.remove(o)

        return ordered_actors, rules
    def test_teams(self):
        # Normal team
        owner1 = Owner("team", self.team.slug)
        actor1 = ActorTuple(self.team.id, Team)

        # Team that doesn't exist
        owner2 = Owner("team", "nope")
        actor2 = None

        # A team that's not ours
        otherteam = Team.objects.exclude(
            projectteam__project_id=self.project.id)[0]
        owner3 = Owner("team", otherteam.slug)
        actor3 = None

        assert resolve_actors([owner1, owner2, owner3], self.project.id) == {
            owner1: actor1,
            owner2: actor2,
            owner3: actor3,
        }
    def test_users(self):
        # Normal user
        owner1 = Owner("user", self.user.email)
        actor1 = ActorTuple(self.user.id, User)

        # An extra secondary email
        email1 = self.create_useremail(self.user, None, is_verified=True).email
        owner2 = Owner("user", email1)
        actor2 = actor1  # They map to the same user since it's just a secondary email

        # Another secondary email, that isn't verified
        email2 = self.create_useremail(self.user, None,
                                       is_verified=False).email
        owner3 = Owner("user", email2)
        # Intentionally allow unverified emails
        # actor3 = None
        actor3 = actor1

        # An entirely unknown user
        owner4 = Owner("user", "nope")
        actor4 = None

        # A user that doesn't belong with us
        otheruser = self.create_user()
        owner5 = Owner("user", otheruser.email)
        actor5 = None

        # Case-insensitive for user
        owner6 = Owner("user", self.user.email.upper())
        actor6 = actor1

        assert resolve_actors([owner1, owner2, owner3, owner4, owner5, owner6],
                              self.project.id) == {
                                  owner1: actor1,
                                  owner2: actor2,
                                  owner3: actor3,
                                  owner4: actor4,
                                  owner5: actor5,
                                  owner6: actor6,
                              }
 def test_no_actors(self):
     assert resolve_actors([], self.project.id) == {}