Skip to content

Commit

Permalink
Merge branch 'master' into feat/add-react-hydration-errors-inbound-fi…
Browse files Browse the repository at this point in the history
…lter
  • Loading branch information
priscilawebdev authored Mar 3, 2023
2 parents 9940a17 + e72c644 commit 2413734
Show file tree
Hide file tree
Showing 135 changed files with 2,985 additions and 2,802 deletions.
4 changes: 0 additions & 4 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@
/src/sentry/migrations/ @getsentry/owners-migrations
/src/sentry/*/migrations/ @getsentry/owners-migrations

## API Owners for unowned endpoints / serializers
/src/**/endpoints/ @getsentry/owners-api
/src/sentry/api/ @getsentry/owners-api

## Snuba
/src/sentry/eventstream/ @getsentry/owners-snuba
/src/sentry/utils/snuba.py @getsentry/owners-snuba @getsentry/discover-n-dashboards
Expand Down
1 change: 1 addition & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
version: 2
labels: []
updates:
- package-ecosystem: npm
open-pull-requests-limit: 10
Expand Down
3 changes: 3 additions & 0 deletions .github/labels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
- name: 'Trigger: Revert'
color: '3E5E06'
description: 'add to a merged PR to revert it (skips CI)'
- name: 'Trigger: Visual Snapshot'
color: '3E5E06'
description: 'add to a PR to run a visual snapshot diff'

# Unito - notion.so/52d10dbfad474328850319e48b057a5b
- name: 'Sync: Jira'
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/bump-sentry-in-getsentry.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ jobs:
git push origin master && exit 0
# There's a little bit of network delay here that suffices
# as a small sleep.
git pull --rebase origin master
git \
-c user.name=getsentry-bot \
-c [email protected] \
pull --rebase origin master
done
# 5th and final attempt.
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@popperjs/core": "^2.11.5",
"@react-aria/button": "^3.3.4",
"@react-aria/focus": "^3.5.0",
"@react-aria/gridlist": "^3.1.2",
"@react-aria/interactions": "^3.7.0",
"@react-aria/listbox": "^3.5.1",
"@react-aria/menu": "^3.3.0",
Expand Down
2 changes: 1 addition & 1 deletion requirements-base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ requests>=2.25.1
rfc3339-validator>=0.1.2
rfc3986-validator>=0.1.1
# [end] jsonschema format validators
sentry-arroyo>=2.6.0
sentry-arroyo>=2.7.1
sentry-relay>=0.8.19
sentry-sdk>=1.15.0
snuba-sdk>=1.0.5
Expand Down
4 changes: 2 additions & 2 deletions requirements-dev-frozen.txt
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ rfc3986-validator==0.1.1
rsa==4.8
s3transfer==0.5.2
selenium==4.3.0
sentry-arroyo==2.6.0
sentry-arroyo==2.7.1
sentry-relay==0.8.19
sentry-sdk==1.15.0
simplejson==3.17.6
Expand Down Expand Up @@ -194,7 +194,7 @@ vine==1.3.0
virtualenv==20.14.1
websocket-client==1.3.2
werkzeug==2.1.2
wheel==0.37.1
wheel==0.38.4
wrapt==1.14.1
wsproto==1.1.0
xmlsec==1.3.12
Expand Down
2 changes: 1 addition & 1 deletion requirements-frozen.txt
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ rfc3986-validator==0.1.1
rsa==4.8
s3transfer==0.5.2
selenium==4.3.0
sentry-arroyo==2.6.0
sentry-arroyo==2.7.1
sentry-relay==0.8.19
sentry-sdk==1.15.0
simplejson==3.17.6
Expand Down
71 changes: 51 additions & 20 deletions src/sentry/api/bases/monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@
from sentry.api.bases.project import ProjectPermission
from sentry.api.endpoints.event_attachment_details import EventAttachmentDetailsPermission
from sentry.api.exceptions import ParameterValidationError, ResourceDoesNotExist
from sentry.models import CheckInStatus, Monitor, MonitorCheckIn, Project, ProjectStatus
from sentry.models import (
CheckInStatus,
Monitor,
MonitorCheckIn,
Organization,
Project,
ProjectStatus,
)
from sentry.utils.sdk import bind_organization_context, configure_scope


class InvalidAuthProject(Exception):
pass


class OrganizationMonitorPermission(OrganizationPermission):
scope_map = {
"GET": ["org:read", "org:write", "org:admin"],
Expand Down Expand Up @@ -57,23 +60,56 @@ class MonitorEndpoint(Endpoint):
def respond_invalid() -> Response:
return Response(status=status.HTTP_400_BAD_REQUEST, data={"details": "Invalid monitor"})

def convert_args(self, request: Request, monitor_id: str, *args, **kwargs):
try:
UUID(monitor_id)
except ValueError:
raise ParameterValidationError("Invalid monitor UUID")
def convert_args(
self,
request: Request,
monitor_id: str,
organization_slug: str | None = None,
*args,
**kwargs,
):
organization = None
monitor = None

try:
monitor = Monitor.objects.get(guid=monitor_id)
except Monitor.DoesNotExist:
raise ResourceDoesNotExist
# The only monitor endpoints that do not have the org slug in their
# parameters are the GUID-style checkin endpoints
if organization_slug:
try:
organization = Organization.objects.get_from_cache(slug=organization_slug)
# Try lookup by slug first. This requires organization context since
# slugs are unique only to the organization
monitor = Monitor.objects.get(organization_id=organization.id, slug=monitor_id)
except (Organization.DoesNotExist, Monitor.DoesNotExist):
pass

# Try lookup by GUID
if not monitor:
# Validate GUIDs
try:
UUID(monitor_id)
except ValueError:
# This error is a bit confusing, because this may also mean
# that we've failed to lookup their monitor by slug.
raise ParameterValidationError("Invalid monitor UUID")
# When looking up by guid we don't include the org conditional
# (since GUID lookup allows orgless routes), we will validate
# permissions later in this function
try:
monitor = Monitor.objects.get(guid=monitor_id)
except Monitor.DoesNotExist:
raise ResourceDoesNotExist

project = Project.objects.get_from_cache(id=monitor.project_id)
if project.status != ProjectStatus.VISIBLE:
raise ResourceDoesNotExist

if hasattr(request.auth, "project_id") and project.id != request.auth.project_id:
raise InvalidAuthProject
raise ResourceDoesNotExist

# When looking up via GUID we do not check the organiation slug,
# validate that the slug matches the org of the monitors project
if organization_slug and project.organization.slug != organization_slug:
raise ResourceDoesNotExist

self.check_object_permissions(request, project)

Expand All @@ -87,11 +123,6 @@ def convert_args(self, request: Request, monitor_id: str, *args, **kwargs):
kwargs.update({"monitor": monitor, "project": project})
return args, kwargs

def handle_exception(self, request: Request, exc: Exception) -> Response:
if isinstance(exc, InvalidAuthProject):
return self.respond(status=400)
return super().handle_exception(request, exc)


class MonitorCheckInEndpoint(MonitorEndpoint):
# TODO(dcramer): this code needs shared with other endpoints as its security focused
Expand Down
6 changes: 5 additions & 1 deletion src/sentry/api/endpoints/group_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,11 @@ def _get_context_plugins(self, request: Request, group):

@staticmethod
def __group_hourly_daily_stats(group: Group, environment_ids: Sequence[int]):
get_range = functools.partial(tsdb.get_range, environment_ids=environment_ids)
get_range = functools.partial(
tsdb.get_range,
environment_ids=environment_ids,
tenant_ids={"organization_id": group.project.organization_id},
)
model = get_issue_tsdb_group_model(group.issue_category)
now = timezone.now()
hourly_stats = tsdb.rollup(
Expand Down
5 changes: 4 additions & 1 deletion src/sentry/api/endpoints/group_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ def get(self, request: Request, group) -> Response:
raise ResourceDoesNotExist

data = tsdb.get_range(
model=tsdb.models.group, keys=[group.id], **self._parse_args(request, environment_id)
model=tsdb.models.group,
keys=[group.id],
**self._parse_args(request, environment_id),
tenant_ids={"organization_id": group.project.organization_id},
)[group.id]

return Response(data)
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ def get(self, request: Request, sentry_app) -> Response:
"""

views = tsdb.get_range(
model=tsdb.models.sentry_app_viewed, keys=[sentry_app.id], **self._parse_args(request)
model=tsdb.models.sentry_app_viewed,
keys=[sentry_app.id],
**self._parse_args(request),
tenant_ids={"organization_id": sentry_app.owner.id},
)[sentry_app.id]

component_interactions = tsdb.get_range(
Expand All @@ -39,6 +42,7 @@ def get(self, request: Request, sentry_app) -> Response:
for component in sentry_app.components.all()
],
**self._parse_args(request),
tenant_ids={"organization_id": sentry_app.owner.id},
)

return Response(
Expand Down
1 change: 1 addition & 0 deletions src/sentry/api/endpoints/issue_occurrence.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def post(self, request: Request) -> Response:
dummy_occurrence = dict(load_data("generic-event-profiling"))
dummy_occurrence["event"]["received"] = datetime.utcnow().isoformat()
dummy_occurrence["event"]["timestamp"] = datetime.utcnow().isoformat()
dummy_occurrence["detection_time"] = datetime.utcnow().timestamp()
project_id = request.query_params.get("project_id")
if project_id:
project = Project.objects.get(id=project_id)
Expand Down
11 changes: 9 additions & 2 deletions src/sentry/api/endpoints/monitor_checkins.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from django.db import transaction
from drf_spectacular.utils import extend_schema
from rest_framework.exceptions import Throttled
from rest_framework.exceptions import ParseError, Throttled
from rest_framework.request import Request
from rest_framework.response import Response

Expand All @@ -15,6 +15,7 @@
from sentry.api.paginator import OffsetPaginator
from sentry.api.serializers import serialize
from sentry.api.serializers.models.monitorcheckin import MonitorCheckInSerializerResponse
from sentry.api.utils import get_date_range_from_params
from sentry.api.validators import MonitorCheckInValidator
from sentry.apidocs.constants import (
RESPONSE_BAD_REQUEST,
Expand Down Expand Up @@ -77,7 +78,13 @@ def get(
if project.organization.slug != organization_slug:
return self.respond_invalid()

queryset = MonitorCheckIn.objects.filter(monitor_id=monitor.id)
start, end = get_date_range_from_params(request.GET)
if start is None or end is None:
raise ParseError(detail="Invalid date range")

queryset = MonitorCheckIn.objects.filter(
monitor_id=monitor.id, date_added__gte=start, date_added__lte=end
)

return self.paginate(
request=request,
Expand Down
8 changes: 0 additions & 8 deletions src/sentry/api/endpoints/organization_monitor_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,6 @@ def get(
"""
Retrieves details for a monitor.
"""
if organization_slug:
if project.organization.slug != organization_slug:
return self.respond_invalid()

return self.respond(serialize(monitor, request.user))

@extend_schema(
Expand All @@ -75,10 +71,6 @@ def put(
"""
Update a monitor.
"""
if organization_slug:
if project.organization.slug != organization_slug:
return self.respond_invalid()

validator = MonitorValidator(
data=request.data,
partial=True,
Expand Down
4 changes: 0 additions & 4 deletions src/sentry/api/endpoints/organization_monitor_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ class OrganizationMonitorStatsEndpoint(MonitorEndpoint, StatsMixin):
def get(
self, request: Request, project, monitor, organization_slug: str | None = None
) -> Response:
if organization_slug:
if project.organization.slug != organization_slug:
return self.respond_invalid()

args = self._parse_args(request)

stats = {}
Expand Down
5 changes: 4 additions & 1 deletion src/sentry/api/endpoints/organization_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,10 @@ def get(self, request: Request, organization) -> Response:
if stat_model is None:
raise ValueError(f"Invalid group: {group}, stat: {stat}")
data = tsdb.get_range(
model=stat_model, keys=keys, **self._parse_args(request, **query_kwargs)
model=stat_model,
keys=keys,
**self._parse_args(request, **query_kwargs),
tenant_ids={"organization_id": organization.id},
)

if group == "organization":
Expand Down
5 changes: 4 additions & 1 deletion src/sentry/api/endpoints/project_group_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ def get(self, request: Request, project) -> Response:
return Response(status=204)

data = tsdb.get_range(
model=tsdb.models.group, keys=group_ids, **self._parse_args(request, environment_id)
model=tsdb.models.group,
keys=group_ids,
**self._parse_args(request, environment_id),
tenant_ids={"organization_id": project.organization_id},
)

return Response({str(k): v for k, v in data.items()})
7 changes: 6 additions & 1 deletion src/sentry/api/endpoints/project_servicehook_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ def get(self, request: Request, project, hook_id) -> Response:

stats = {}
for model, name in ((tsdb.models.servicehook_fired, "total"),):
result = tsdb.get_range(model=model, keys=[hook.id], **stat_args)[hook.id]
result = tsdb.get_range(
model=model,
keys=[hook.id],
**stat_args,
tenant_ids={"organization_id": project.organization_id},
)[hook.id]
for ts, count in result:
stats.setdefault(int(ts), {})[name] = count

Expand Down
8 changes: 4 additions & 4 deletions src/sentry/api/endpoints/project_stacktrace_link.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,18 +267,18 @@ def fetch_codecov_data(
# or getting ref from git blame was successful
codecov_data = None
if not fetch_commit_sha or ref:
lineCoverage, codecovUrl = get_codecov_data(
line_coverage, codecov_url = get_codecov_data(
repo=repo.name,
service=service,
ref=ref if ref else branch,
ref_type="sha" if ref else "branch",
path=path,
organization=org,
)
if lineCoverage and codecovUrl:
if line_coverage and codecov_url:
codecov_data = {
"lineCoverage": lineCoverage,
"coverageUrl": codecovUrl,
"lineCoverage": line_coverage,
"coverageUrl": codecov_url,
"status": 200,
}
return codecov_data
Expand Down
5 changes: 4 additions & 1 deletion src/sentry/api/endpoints/project_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ def get(self, request: Request, project) -> Response:
raise ValueError("Invalid stat: %s" % stat)

data = tsdb.get_range(
model=stat_model, keys=[project.id], **self._parse_args(request, **query_kwargs)
model=stat_model,
keys=[project.id],
**self._parse_args(request, **query_kwargs),
tenant_ids={"organization_id": project.organization_id},
)[project.id]

return Response(data)
1 change: 1 addition & 0 deletions src/sentry/api/endpoints/team_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def get(self, request: Request, team) -> Response:
model=tsdb.models.project,
keys=[p.id for p in projects],
**self._parse_args(request, environment_id),
tenant_ids={"organization_id": team.organization_id},
).values()
)

Expand Down
Loading

0 comments on commit 2413734

Please sign in to comment.