Browse Source

fix(discover): Non Team projects weren't saveable (#20175)

- If a user wasn't in a team they couldn't save discover queries with
  projects that still belong to the organization
- If there are projects in the query that aren't in the validated set of
  projects then we should deny permission
William Mak 4 years ago
parent
commit
4fb7696d7a

+ 2 - 2
src/sentry/discover/endpoints/serializers.py

@@ -176,8 +176,8 @@ class DiscoverSavedQuerySerializer(serializers.Serializer):
         if projects == ALL_ACCESS_PROJECTS or len(projects) == 0:
             return projects
 
-        # Params will have project_ids that have been validated
-        if projects != set(self.context["params"]["project_id"]):
+        # Check that there aren't projects in the query the user doesn't have access to
+        if len(projects - set(self.context["params"]["project_id"])) > 0:
             raise PermissionDenied
 
         return projects

+ 55 - 1
tests/snuba/api/endpoints/test_discover_saved_queries.py

@@ -366,9 +366,46 @@ class DiscoverSavedQueriesVersion2Test(DiscoverSavedQueryBase):
         assert response.status_code == 201, response.content
         assert DiscoverSavedQuery.objects.filter(name="project query").exists()
 
+    def test_save_with_org_projects(self):
+        project = self.create_project(organization=self.org)
+        with self.feature(self.feature_name):
+            url = reverse("sentry-api-0-discover-saved-queries", args=[self.org.slug])
+            response = self.client.post(
+                url,
+                {
+                    "name": "project query",
+                    "projects": [project.id],
+                    "fields": ["title", "count()"],
+                    "range": "24h",
+                    "version": 2,
+                },
+            )
+        assert response.status_code == 201, response.content
+        assert DiscoverSavedQuery.objects.filter(name="project query").exists()
+
+    def test_save_with_team_project(self):
+        team = self.create_team(organization=self.org, members=[self.user])
+        project = self.create_project(organization=self.org, teams=[team])
+        self.create_project(organization=self.org, teams=[team])
+        with self.feature(self.feature_name):
+            url = reverse("sentry-api-0-discover-saved-queries", args=[self.org.slug])
+            response = self.client.post(
+                url,
+                {
+                    "name": "project query",
+                    "projects": [project.id],
+                    "fields": ["title", "count()"],
+                    "range": "24h",
+                    "version": 2,
+                },
+            )
+        assert response.status_code == 201, response.content
+        assert DiscoverSavedQuery.objects.filter(name="project query").exists()
+
     def test_save_with_wrong_projects(self):
         other_org = self.create_organization(owner=self.user)
         project = self.create_project(organization=other_org)
+        project2 = self.create_project(organization=self.org)
         with self.feature(self.feature_name):
             url = reverse("sentry-api-0-discover-saved-queries", args=[self.org.slug])
             response = self.client.post(
@@ -385,6 +422,23 @@ class DiscoverSavedQueriesVersion2Test(DiscoverSavedQueryBase):
         assert response.status_code == 403, response.content
         assert not DiscoverSavedQuery.objects.filter(name="project query").exists()
 
+        with self.feature(self.feature_name):
+            url = reverse("sentry-api-0-discover-saved-queries", args=[self.org.slug])
+            response = self.client.post(
+                url,
+                {
+                    "name": "project query",
+                    "projects": [project.id, project2.id],
+                    "fields": ["title", "count()"],
+                    "range": "24h",
+                    "query": "project:{} project:{}".format(project.slug, project2.slug),
+                    "version": 2,
+                },
+            )
+        assert response.status_code == 403, response.content
+        assert not DiscoverSavedQuery.objects.filter(name="project query").exists()
+
+        # Mix of wrong + valid
         with self.feature(self.feature_name):
             url = reverse("sentry-api-0-discover-saved-queries", args=[self.org.slug])
             response = self.client.post(
@@ -394,7 +448,7 @@ class DiscoverSavedQueriesVersion2Test(DiscoverSavedQueryBase):
                     "projects": [-1],
                     "fields": ["title", "count()"],
                     "range": "24h",
-                    "query": "project:{}".format(project.slug),
+                    "query": "project:{} project:{}".format(project.slug, project2.slug),
                     "version": 2,
                 },
             )