55import sentry_sdk
66from django .db import DatabaseError
77from rest_framework import serializers
8- from rest_framework .permissions import BasePermission
98from rest_framework .request import Request
109from rest_framework .response import Response
1110
1211from sentry .api .api_owners import ApiOwner
1312from sentry .api .api_publish_status import ApiPublishStatus
1413from sentry .api .base import region_silo_endpoint
1514from sentry .api .bases import OrganizationEndpoint
15+ from sentry .api .bases .organization import OrganizationPermission
1616from sentry .exceptions import InvalidSearchQuery
1717from sentry .models .dynamicsampling import (
1818 CUSTOM_RULE_DATE_FORMAT ,
@@ -94,7 +94,7 @@ def validate(self, data):
9494 return data
9595
9696
97- class CustomRulePermission (BasePermission ):
97+ class CustomRulePermission (OrganizationPermission ):
9898 scope_map = {
9999 "GET" : [
100100 "org:read" ,
@@ -130,7 +130,10 @@ def post(self, request: Request, organization: Organization) -> Response:
130130 return Response (serializer .errors , status = 400 )
131131
132132 query = serializer .validated_data ["query" ]
133- projects = serializer .validated_data .get ("projects" )
133+ project_ids = serializer .validated_data .get ("projects" )
134+
135+ # project-level permission check
136+ self .get_projects (request , organization , project_ids = set (project_ids ))
134137
135138 try :
136139 condition = get_rule_condition (query )
@@ -145,7 +148,7 @@ def post(self, request: Request, organization: Organization) -> Response:
145148 condition = condition ,
146149 start = start ,
147150 end = end ,
148- project_ids = projects ,
151+ project_ids = project_ids ,
149152 organization_id = organization .id ,
150153 num_samples = NUM_SAMPLES_PER_CUSTOM_RULE ,
151154 sample_rate = 1.0 ,
@@ -154,7 +157,7 @@ def post(self, request: Request, organization: Organization) -> Response:
154157 )
155158
156159 # schedule update for affected project configs
157- _schedule_invalidate_project_configs (organization , projects )
160+ _schedule_invalidate_project_configs (organization , project_ids )
158161
159162 return _rule_to_response (rule )
160163 except UnsupportedSearchQuery as e :
@@ -189,6 +192,9 @@ def get(self, request: Request, organization: Organization) -> Response:
189192 except ValueError :
190193 return Response ({"projects" : ["Invalid project id" ]}, status = 400 )
191194
195+ # project-level permission check
196+ self .get_projects (request , organization , project_ids = set (requested_projects_ids ))
197+
192198 if requested_projects_ids :
193199 org_rule = False
194200 invalid_projects = []
0 commit comments