diff --git a/src/sentry/api/helpers/group_index/validators/group.py b/src/sentry/api/helpers/group_index/validators/group.py index 336b8d8f656ab7..2431c5abd306e4 100644 --- a/src/sentry/api/helpers/group_index/validators/group.py +++ b/src/sentry/api/helpers/group_index/validators/group.py @@ -83,21 +83,27 @@ class GroupValidator(serializers.Serializer[Group]): snoozeDuration = serializers.IntegerField(allow_null=True) def validate_assignedTo(self, value: Actor) -> Actor: - if ( - value - and value.is_user - and not self.context["project"].member_set.filter(user_id=value.id).exists() - ): - raise serializers.ValidationError("Cannot assign to non-team member") + if value and value.is_user: + organization = self.context["organization"] + project = self.context["project"] + # With open membership, any org member can be assigned since they + # can join any team (and thus gain project access) at will. + if organization.flags.allow_joinleave: + if not organization.member_set.filter(user_id=value.id).exists(): + raise serializers.ValidationError("Cannot assign to non-organization member") + elif not project.member_set.filter(user_id=value.id).exists(): + raise serializers.ValidationError("Cannot assign to non-team member") - if ( - value - and value.is_team - and not self.context["project"].teams.filter(id=value.id).exists() - ): - raise serializers.ValidationError( - "Cannot assign to a team without access to the project" - ) + if value and value.is_team: + organization = self.context["organization"] + project = self.context["project"] + # With open membership, allow assigning any org team. The team's + # org membership is already validated by ActorField.to_internal_value. + if not organization.flags.allow_joinleave: + if not project.teams.filter(id=value.id).exists(): + raise serializers.ValidationError( + "Cannot assign to a team without access to the project" + ) return value