Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/sentry/api/bases/incident.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ class IncidentPermission(OrganizationPermission):
"project:write",
"project:admin",
],
"POST": ["org:write", "org:admin", "project:read", "project:write", "project:admin"],
"PUT": ["org:write", "org:admin", "project:read", "project:write", "project:admin"],
"DELETE": ["org:write", "org:admin", "project:read", "project:write", "project:admin"],
"POST": ["org:write", "org:admin", "project:write", "project:admin"],
"PUT": ["org:write", "org:admin", "project:write", "project:admin"],
"DELETE": ["org:write", "org:admin", "project:write", "project:admin"],
Comment thread
dcramer marked this conversation as resolved.
Outdated
}


Expand Down
59 changes: 45 additions & 14 deletions src/sentry/api/bases/organization.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from sentry.models.project import Project
from sentry.models.release import Release
from sentry.models.releases.release_project import ReleaseProject
from sentry.models.team import Team
from sentry.organizations.services.organization import (
RpcOrganization,
RpcUserOrganizationContext,
Expand Down Expand Up @@ -158,16 +159,16 @@ class OrganizationIntegrationsPermission(OrganizationPermission):
class OrganizationIntegrationsLoosePermission(OrganizationPermission):
scope_map = {
"GET": ["org:read", "org:write", "org:admin", "org:integrations", "org:ci"],
"POST": ["org:read", "org:write", "org:admin", "org:integrations"],
"PUT": ["org:read", "org:write", "org:admin", "org:integrations"],
"POST": ["org:write", "org:admin", "org:integrations"],
"PUT": ["org:write", "org:admin", "org:integrations"],
"DELETE": ["org:admin", "org:integrations"],
}


class OrganizationCodeMappingsBulkPermission(OrganizationPermission):
scope_map = {
"GET": ["org:read", "org:write", "org:admin", "org:integrations", "org:ci"],
"POST": ["org:read", "org:write", "org:admin", "org:integrations", "org:ci"],
"POST": ["org:write", "org:admin", "org:integrations", "org:ci"],
}


Expand Down Expand Up @@ -212,37 +213,67 @@ class OrganizationSearchPermission(OrganizationPermission):
class OrganizationDataExportPermission(OrganizationPermission):
scope_map = {
"GET": ["event:read", "event:write", "event:admin"],
"POST": ["event:read", "event:write", "event:admin"],
"POST": ["event:write", "event:admin"],
}


def _has_any_team_scope(request: Request, scope: str) -> bool:
if not request.access.team_ids_with_membership:
return False

teams = Team.objects.filter(id__in=request.access.team_ids_with_membership)
return any(request.access.has_team_scope(team, scope) for team in teams)


class OrganizationAlertRulePermission(OrganizationPermission):
scope_map = {
"GET": ["org:read", "org:write", "org:admin", "alerts:read"],
# grant org:read permission, but raise permission denied if the members aren't allowed
# to create alerts and the user isn't a team admin
"POST": ["org:read", "org:write", "org:admin", "alerts:write"],
"POST": ["org:write", "org:admin", "alerts:write"],
"PUT": ["org:write", "org:admin", "alerts:write"],
"DELETE": ["org:write", "org:admin", "alerts:write"],
}

def has_object_permission(
self,
request: Request,
view: APIView,
organization: Organization | RpcOrganization | RpcUserOrganizationContext,
) -> bool:
if super().has_object_permission(request, view, organization):
return True

return request.method in {"POST", "PUT", "DELETE"} and _has_any_team_scope(
request, "alerts:write"
)
Comment thread
cursor[bot] marked this conversation as resolved.


class OrganizationDetectorPermission(OrganizationPermission):
scope_map = {
"GET": ["org:read", "org:write", "org:admin", "alerts:read"],
# grant org:read permission, but raise permission denied if the members aren't allowed
# to create alerts and the user isn't a team admin
"POST": ["org:read", "org:write", "org:admin", "alerts:write"],
"PUT": ["org:read", "org:write", "org:admin", "alerts:write"],
"DELETE": ["org:read", "org:write", "org:admin", "alerts:write"],
"POST": ["org:write", "org:admin", "alerts:write"],
"PUT": ["org:write", "org:admin", "alerts:write"],
"DELETE": ["org:write", "org:admin", "alerts:write"],
}

def has_object_permission(
self,
request: Request,
view: APIView,
organization: Organization | RpcOrganization | RpcUserOrganizationContext,
) -> bool:
if super().has_object_permission(request, view, organization):
return True

return request.method in {"POST", "PUT", "DELETE"} and _has_any_team_scope(
request, "alerts:write"
)


class OrgAuthTokenPermission(OrganizationPermission):
scope_map = {
"GET": ["org:read", "org:write", "org:admin"],
"POST": ["org:read", "org:write", "org:admin"],
"PUT": ["org:read", "org:write", "org:admin"],
"POST": ["org:write", "org:admin"],
"PUT": ["org:write", "org:admin"],
"DELETE": ["org:write", "org:admin"],
}

Expand Down
2 changes: 1 addition & 1 deletion src/sentry/api/endpoints/project_repo_path_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class ProjectRepoPathParsingEndpointLoosePermission(ProjectPermission):
"""

scope_map = {
"POST": ["org:read", "project:write", "project:admin"],
"POST": ["project:write"],
}


Expand Down
6 changes: 3 additions & 3 deletions src/sentry/dashboards/endpoints/organization_dashboards.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,9 @@ def sync_prebuilt_dashboards(organization: Organization) -> None:
class OrganizationDashboardsPermission(OrganizationPermission):
scope_map = {
"GET": ["org:read", "org:write", "org:admin"],
"POST": ["org:read", "org:write", "org:admin"],
"PUT": ["org:read", "org:write", "org:admin"],
"DELETE": ["org:read", "org:write", "org:admin"],
"POST": ["org:write", "org:admin"],
"PUT": ["org:write", "org:admin"],
"DELETE": ["org:write", "org:admin"],
}

def has_object_permission(
Expand Down
25 changes: 21 additions & 4 deletions src/sentry/discover/endpoints/discover_key_transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,31 @@
from sentry.models.team import Team


def _has_any_team_scope(request: Request, scopes: list[str]) -> bool:
if not request.access.team_ids_with_membership:
return False

teams = Team.objects.filter(id__in=request.access.team_ids_with_membership)
return any(
any(request.access.has_team_scope(team, scope) for scope in scopes) for team in teams
)
Comment thread
cursor[bot] marked this conversation as resolved.
Outdated


class KeyTransactionPermission(OrganizationPermission):
scope_map = {
"GET": ["org:read"],
"POST": ["org:read"],
"PUT": ["org:read"],
"DELETE": ["org:read"],
"GET": ["project:read"],
"POST": ["project:write"],
"PUT": ["project:write"],
"DELETE": ["project:write"],
}

def has_object_permission(self, request: Request, view, obj: object) -> bool:
if super().has_object_permission(request, view, obj):
return True

allowed_scopes = self.scope_map.get(request.method or "", [])
return _has_any_team_scope(request, allowed_scopes)


@cell_silo_endpoint
class KeyTransactionEndpoint(KeyTransactionBase):
Expand Down
2 changes: 1 addition & 1 deletion src/sentry/issues/endpoints/project_user_issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ class WebVitalsIssueDataSerializer(ProjectUserIssueRequestSerializer):
class ProjectUserIssuePermission(ProjectPermission):
scope_map = {
"GET": [],
"POST": ["event:read", "event:write", "event:admin"],
"POST": ["event:write", "event:admin"],
"PUT": [],
"DELETE": [],
}
Expand Down
8 changes: 4 additions & 4 deletions src/sentry/replays/endpoints/project_replay_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@

class ReplayDetailsPermission(ProjectPermission):
scope_map = {
"GET": ["project:read", "project:write", "project:admin"],
"POST": ["project:write", "project:admin"],
"PUT": ["project:write", "project:admin"],
"DELETE": ["project:read", "project:write", "project:admin"],
"GET": ["project:read"],
"POST": ["project:write"],
"PUT": ["project:write"],
"DELETE": ["event:write"],
Comment thread
cursor[bot] marked this conversation as resolved.
Outdated
}


Expand Down
4 changes: 2 additions & 2 deletions src/sentry/replays/endpoints/project_replay_summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@

class ReplaySummaryPermission(ProjectPermission):
scope_map = {
"GET": ["event:read", "event:write", "event:admin"],
"POST": ["event:read", "event:write", "event:admin"],
"GET": ["event:read"],
"POST": ["event:write"],
"PUT": [],
"DELETE": [],
}
Expand Down
Loading