From 50fcc6382e52892fc072f8fcb98ea6589f6f514c Mon Sep 17 00:00:00 2001 From: Richard Roggenkemper Date: Thu, 4 Jan 2024 14:50:14 -0800 Subject: [PATCH 1/4] draft of inboudn filter default --- src/sentry/api/endpoints/team_projects.py | 5 ++ .../api/helpers/default_inbound_filters.py | 31 +++++++++++ .../api/endpoints/test_team_projects.py | 52 +++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 src/sentry/api/helpers/default_inbound_filters.py diff --git a/src/sentry/api/endpoints/team_projects.py b/src/sentry/api/endpoints/team_projects.py index 888941255d51fa..9b8b1138ac4b39 100644 --- a/src/sentry/api/endpoints/team_projects.py +++ b/src/sentry/api/endpoints/team_projects.py @@ -12,6 +12,7 @@ from sentry.api.base import EnvironmentMixin, region_silo_endpoint from sentry.api.bases.team import TeamEndpoint, TeamPermission from sentry.api.fields.sentry_slug import SentrySerializerSlugField +from sentry.api.helpers.default_inbound_filters import set_default_inbound_filters from sentry.api.paginator import OffsetPaginator from sentry.api.serializers import ProjectSummarySerializer, serialize from sentry.api.serializers.models.project import OrganizationProjectResponse, ProjectSerializer @@ -182,6 +183,10 @@ def post(self, request: Request, team) -> Response: # XXX: create sample event? + # Turns on some inbound filters by default for new Javascript platform projects + if project.platform and project.platform.startswith("javascript"): + set_default_inbound_filters(project) + self.create_audit_entry( request=request, organization=team.organization, diff --git a/src/sentry/api/helpers/default_inbound_filters.py b/src/sentry/api/helpers/default_inbound_filters.py new file mode 100644 index 00000000000000..39efe652cc2701 --- /dev/null +++ b/src/sentry/api/helpers/default_inbound_filters.py @@ -0,0 +1,31 @@ +from sentry.ingest import inbound_filters + + +# Turns on certain inbound filters by default for project. +def set_default_inbound_filters(project): + filters = [ + "browser-extensions", + "legacy-browsers", + "web-crawlers", + "filtered-transaction", + ] + + for filter_id in filters: + if filter_id == "legacy-browsers": + state = { + "subfilters": [ + "ie_pre_9", + "ie9", + "ie10", + "ie11", + "safari_pre_6", + "opera_pre_15", + "opera_mini_pre_8", + "android_pre_4", + "edge_pre_79", + ] + } + else: + state = {"active": True} + + inbound_filters.set_filter_state(filter_id, project, state) diff --git a/tests/sentry/api/endpoints/test_team_projects.py b/tests/sentry/api/endpoints/test_team_projects.py index a509a6d5c083af..7c2f9f39efe4d5 100644 --- a/tests/sentry/api/endpoints/test_team_projects.py +++ b/tests/sentry/api/endpoints/test_team_projects.py @@ -1,3 +1,4 @@ +from sentry.ingest import inbound_filters from sentry.models.project import Project from sentry.models.rule import Rule from sentry.notifications.types import FallthroughChoiceType @@ -143,3 +144,54 @@ def test_without_default_rules(self): ) project = Project.objects.get(id=response.data["id"]) assert not Rule.objects.filter(project=project).exists() + + def test_default_inbound_filters(self): + filters = ["browser-extensions", "legacy-browsers", "web-crawlers", "filtered-transaction"] + python_response = self.get_success_response( + self.organization.slug, + self.team.slug, + **self.data, + status_code=201, + ) + + python_project = Project.objects.get(id=python_response.data["id"]) + + python_filter_states = { + filter_id: inbound_filters.get_filter_state(filter_id, python_project) + for filter_id in filters + } + + assert not python_filter_states["browser-extensions"] + assert not python_filter_states["legacy-browsers"] + assert not python_filter_states["web-crawlers"] + assert python_filter_states["filtered-transaction"] + + project_data = {"name": "foo", "slug": "baz", "platform": "javascript-react"} + javascript_response = self.get_success_response( + self.organization.slug, + self.team.slug, + **project_data, + status_code=201, + ) + + javascript_project = Project.objects.get(id=javascript_response.data["id"]) + + javascript_filter_states = { + filter_id: inbound_filters.get_filter_state(filter_id, javascript_project) + for filter_id in filters + } + + assert javascript_filter_states["browser-extensions"] + assert set(javascript_filter_states["legacy-browsers"]) == { + "ie_pre_9", + "ie9", + "ie10", + "ie11", + "safari_pre_6", + "opera_pre_15", + "opera_mini_pre_8", + "android_pre_4", + "edge_pre_79", + } + assert javascript_filter_states["web-crawlers"] + assert javascript_filter_states["filtered-transaction"] From b4844b2734899e04fc5259a7cd3a27824deb7fa2 Mon Sep 17 00:00:00 2001 From: Richard Roggenkemper Date: Thu, 4 Jan 2024 15:29:25 -0800 Subject: [PATCH 2/4] fix types --- .../api/helpers/default_inbound_filters.py | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/sentry/api/helpers/default_inbound_filters.py b/src/sentry/api/helpers/default_inbound_filters.py index 39efe652cc2701..e7d99473e108a0 100644 --- a/src/sentry/api/helpers/default_inbound_filters.py +++ b/src/sentry/api/helpers/default_inbound_filters.py @@ -1,8 +1,11 @@ +from typing import Dict, List, Union + from sentry.ingest import inbound_filters # Turns on certain inbound filters by default for project. def set_default_inbound_filters(project): + state: Dict[str, Union[bool, List[str]]] = {} filters = [ "browser-extensions", "legacy-browsers", @@ -12,20 +15,18 @@ def set_default_inbound_filters(project): for filter_id in filters: if filter_id == "legacy-browsers": - state = { - "subfilters": [ - "ie_pre_9", - "ie9", - "ie10", - "ie11", - "safari_pre_6", - "opera_pre_15", - "opera_mini_pre_8", - "android_pre_4", - "edge_pre_79", - ] - } + state["subfilters"] = [ + "ie_pre_9", + "ie9", + "ie10", + "ie11", + "safari_pre_6", + "opera_pre_15", + "opera_mini_pre_8", + "android_pre_4", + "edge_pre_79", + ] else: - state = {"active": True} + state["active"] = True inbound_filters.set_filter_state(filter_id, project, state) From 07c459042d797e8773cb263821fb06b420cd41ad Mon Sep 17 00:00:00 2001 From: Richard Roggenkemper Date: Fri, 5 Jan 2024 10:50:39 -0800 Subject: [PATCH 3/4] fix test --- tests/sentry/api/endpoints/test_team_projects.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/tests/sentry/api/endpoints/test_team_projects.py b/tests/sentry/api/endpoints/test_team_projects.py index 7c2f9f39efe4d5..eca7a81d2cb602 100644 --- a/tests/sentry/api/endpoints/test_team_projects.py +++ b/tests/sentry/api/endpoints/test_team_projects.py @@ -182,16 +182,6 @@ def test_default_inbound_filters(self): } assert javascript_filter_states["browser-extensions"] - assert set(javascript_filter_states["legacy-browsers"]) == { - "ie_pre_9", - "ie9", - "ie10", - "ie11", - "safari_pre_6", - "opera_pre_15", - "opera_mini_pre_8", - "android_pre_4", - "edge_pre_79", - } + assert javascript_filter_states["legacy-browsers"] assert javascript_filter_states["web-crawlers"] assert javascript_filter_states["filtered-transaction"] From 85001d992d8e5b416c57c5b498f0c8d910ad092f Mon Sep 17 00:00:00 2001 From: Richard Roggenkemper Date: Mon, 8 Jan 2024 13:33:39 -0800 Subject: [PATCH 4/4] add feature flag --- src/sentry/api/endpoints/team_projects.py | 8 ++++++-- tests/sentry/api/endpoints/test_team_projects.py | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/sentry/api/endpoints/team_projects.py b/src/sentry/api/endpoints/team_projects.py index 9b8b1138ac4b39..7b81b0336f18b8 100644 --- a/src/sentry/api/endpoints/team_projects.py +++ b/src/sentry/api/endpoints/team_projects.py @@ -6,7 +6,7 @@ from rest_framework.request import Request from rest_framework.response import Response -from sentry import audit_log +from sentry import audit_log, features from sentry.api.api_owners import ApiOwner from sentry.api.api_publish_status import ApiPublishStatus from sentry.api.base import EnvironmentMixin, region_silo_endpoint @@ -184,7 +184,11 @@ def post(self, request: Request, team) -> Response: # XXX: create sample event? # Turns on some inbound filters by default for new Javascript platform projects - if project.platform and project.platform.startswith("javascript"): + if ( + features.has("organizations:default-inbound-filters", team.organization) + and project.platform + and project.platform.startswith("javascript") + ): set_default_inbound_filters(project) self.create_audit_entry( diff --git a/tests/sentry/api/endpoints/test_team_projects.py b/tests/sentry/api/endpoints/test_team_projects.py index eca7a81d2cb602..fbce4233ee6e41 100644 --- a/tests/sentry/api/endpoints/test_team_projects.py +++ b/tests/sentry/api/endpoints/test_team_projects.py @@ -145,6 +145,7 @@ def test_without_default_rules(self): project = Project.objects.get(id=response.data["id"]) assert not Rule.objects.filter(project=project).exists() + @with_feature("organizations:default-inbound-filters") def test_default_inbound_filters(self): filters = ["browser-extensions", "legacy-browsers", "web-crawlers", "filtered-transaction"] python_response = self.get_success_response(