|
29 | 29 | from sentry.models.project import Project |
30 | 30 | from sentry.models.release import Release |
31 | 31 | from sentry.models.releases.release_project import ReleaseProject |
| 32 | +from sentry.models.team import Team |
32 | 33 | from sentry.organizations.services.organization import ( |
33 | 34 | RpcOrganization, |
34 | 35 | RpcUserOrganizationContext, |
@@ -158,16 +159,16 @@ class OrganizationIntegrationsPermission(OrganizationPermission): |
158 | 159 | class OrganizationIntegrationsLoosePermission(OrganizationPermission): |
159 | 160 | scope_map = { |
160 | 161 | "GET": ["org:read", "org:write", "org:admin", "org:integrations", "org:ci"], |
161 | | - "POST": ["org:read", "org:write", "org:admin", "org:integrations"], |
162 | | - "PUT": ["org:read", "org:write", "org:admin", "org:integrations"], |
| 162 | + "POST": ["org:write", "org:admin", "org:integrations"], |
| 163 | + "PUT": ["org:write", "org:admin", "org:integrations"], |
163 | 164 | "DELETE": ["org:admin", "org:integrations"], |
164 | 165 | } |
165 | 166 |
|
166 | 167 |
|
167 | 168 | class OrganizationCodeMappingsBulkPermission(OrganizationPermission): |
168 | 169 | scope_map = { |
169 | 170 | "GET": ["org:read", "org:write", "org:admin", "org:integrations", "org:ci"], |
170 | | - "POST": ["org:read", "org:write", "org:admin", "org:integrations", "org:ci"], |
| 171 | + "POST": ["org:write", "org:admin", "org:integrations", "org:ci"], |
171 | 172 | } |
172 | 173 |
|
173 | 174 |
|
@@ -195,62 +196,101 @@ class OrganizationUserReportsPermission(OrganizationPermission): |
195 | 196 |
|
196 | 197 | class OrganizationPinnedSearchPermission(OrganizationPermission): |
197 | 198 | scope_map = { |
198 | | - "PUT": ["org:read", "org:write", "org:admin"], |
199 | | - "DELETE": ["org:read", "org:write", "org:admin"], |
| 199 | + "PUT": ["org:searches"], |
| 200 | + "DELETE": ["org:searches"], |
200 | 201 | } |
201 | 202 |
|
202 | 203 |
|
203 | 204 | class OrganizationSearchPermission(OrganizationPermission): |
204 | 205 | scope_map = { |
205 | | - "GET": ["org:read", "org:write", "org:admin"], |
206 | | - "POST": ["org:read", "org:write", "org:admin"], |
207 | | - "PUT": ["org:read", "org:write", "org:admin"], |
208 | | - "DELETE": ["org:read", "org:write", "org:admin"], |
| 206 | + "GET": ["org:read", "org:searches"], |
| 207 | + "POST": ["org:searches"], |
| 208 | + "PUT": ["org:searches"], |
| 209 | + "DELETE": ["org:searches"], |
| 210 | + } |
| 211 | + |
| 212 | + |
| 213 | +class OrganizationPreferencePermission(OrganizationPermission): |
| 214 | + scope_map = { |
| 215 | + "GET": ["user:preferences"], |
| 216 | + "POST": ["user:preferences"], |
| 217 | + "PUT": ["user:preferences"], |
| 218 | + "DELETE": ["user:preferences"], |
209 | 219 | } |
210 | 220 |
|
211 | 221 |
|
212 | 222 | class OrganizationDataExportPermission(OrganizationPermission): |
213 | 223 | scope_map = { |
214 | 224 | "GET": ["event:read", "event:write", "event:admin"], |
215 | | - "POST": ["event:read", "event:write", "event:admin"], |
| 225 | + "POST": ["event:write", "event:admin"], |
216 | 226 | } |
217 | 227 |
|
218 | 228 |
|
| 229 | +def _has_any_team_scope(request: Request, scope: str) -> bool: |
| 230 | + if not request.access.team_ids_with_membership: |
| 231 | + return False |
| 232 | + |
| 233 | + teams = Team.objects.filter(id__in=request.access.team_ids_with_membership) |
| 234 | + return any(request.access.has_team_scope(team, scope) for team in teams) |
| 235 | + |
| 236 | + |
219 | 237 | class OrganizationAlertRulePermission(OrganizationPermission): |
220 | 238 | scope_map = { |
221 | 239 | "GET": ["org:read", "org:write", "org:admin", "alerts:read"], |
222 | | - # grant org:read permission, but raise permission denied if the members aren't allowed |
223 | | - # to create alerts and the user isn't a team admin |
224 | | - "POST": ["org:read", "org:write", "org:admin", "alerts:write"], |
| 240 | + "POST": ["org:write", "org:admin", "alerts:write"], |
225 | 241 | "PUT": ["org:write", "org:admin", "alerts:write"], |
226 | 242 | "DELETE": ["org:write", "org:admin", "alerts:write"], |
227 | 243 | } |
228 | 244 |
|
| 245 | + def has_object_permission( |
| 246 | + self, |
| 247 | + request: Request, |
| 248 | + view: APIView, |
| 249 | + organization: Organization | RpcOrganization | RpcUserOrganizationContext, |
| 250 | + ) -> bool: |
| 251 | + if super().has_object_permission(request, view, organization): |
| 252 | + return True |
| 253 | + |
| 254 | + return request.method in {"POST", "PUT", "DELETE"} and _has_any_team_scope( |
| 255 | + request, "alerts:write" |
| 256 | + ) |
| 257 | + |
229 | 258 |
|
230 | 259 | class OrganizationDetectorPermission(OrganizationPermission): |
231 | 260 | scope_map = { |
232 | 261 | "GET": ["org:read", "org:write", "org:admin", "alerts:read"], |
233 | | - # grant org:read permission, but raise permission denied if the members aren't allowed |
234 | | - # to create alerts and the user isn't a team admin |
235 | | - "POST": ["org:read", "org:write", "org:admin", "alerts:write"], |
236 | | - "PUT": ["org:read", "org:write", "org:admin", "alerts:write"], |
237 | | - "DELETE": ["org:read", "org:write", "org:admin", "alerts:write"], |
| 262 | + "POST": ["org:write", "org:admin", "alerts:write"], |
| 263 | + "PUT": ["org:write", "org:admin", "alerts:write"], |
| 264 | + "DELETE": ["org:write", "org:admin", "alerts:write"], |
238 | 265 | } |
239 | 266 |
|
| 267 | + def has_object_permission( |
| 268 | + self, |
| 269 | + request: Request, |
| 270 | + view: APIView, |
| 271 | + organization: Organization | RpcOrganization | RpcUserOrganizationContext, |
| 272 | + ) -> bool: |
| 273 | + if super().has_object_permission(request, view, organization): |
| 274 | + return True |
| 275 | + |
| 276 | + return request.method in {"POST", "PUT", "DELETE"} and _has_any_team_scope( |
| 277 | + request, "alerts:write" |
| 278 | + ) |
| 279 | + |
240 | 280 |
|
241 | 281 | class OrgAuthTokenPermission(OrganizationPermission): |
242 | 282 | scope_map = { |
243 | 283 | "GET": ["org:read", "org:write", "org:admin"], |
244 | | - "POST": ["org:read", "org:write", "org:admin"], |
245 | | - "PUT": ["org:read", "org:write", "org:admin"], |
| 284 | + "POST": ["org:write", "org:admin"], |
| 285 | + "PUT": ["org:write", "org:admin"], |
246 | 286 | "DELETE": ["org:write", "org:admin"], |
247 | 287 | } |
248 | 288 |
|
249 | 289 |
|
250 | 290 | class OrganizationFlagWebHookSigningSecretPermission(OrganizationPermission): |
251 | 291 | scope_map = { |
252 | 292 | "GET": ["org:read", "org:write", "org:admin"], |
253 | | - "POST": ["org:read", "org:write", "org:admin"], |
| 293 | + "POST": ["flags:write", "org:write", "org:admin"], |
254 | 294 | "DELETE": ["org:write", "org:admin"], |
255 | 295 | } |
256 | 296 |
|
|
0 commit comments