Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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: 5 additions & 1 deletion src/sentry/data_export/endpoints/data_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from sentry.api.helpers.environments import get_environment_id
from sentry.api.serializers import serialize
from sentry.api.utils import get_date_range_from_params
from sentry.auth.principal import require_user
from sentry.data_export.base import ExportError, ExportQueryType
from sentry.data_export.models import ExportedData
from sentry.data_export.processors.discover import DiscoverProcessor
Expand Down Expand Up @@ -373,6 +374,9 @@ def post(self, request: Request, organization: Organization) -> Response:
Create a new asynchronous or sync file export task depending on requested file size,
and email user upon completion.
"""
# The export is emailed to and downloaded by its user, so a caller with no user
# could never get it.
user_id = require_user(request).id

extra = {
"organization_id": organization.id,
Expand Down Expand Up @@ -423,7 +427,7 @@ def post(self, request: Request, organization: Organization) -> Response:
query_type = ExportQueryType.from_str(validated_data["query_type"])
data_export, created = ExportedData.objects.get_or_create(
organization=organization,
user_id=request.user.id,
user_id=user_id,
query_type=query_type,
query_info=validated_data["query_info"],
date_finished=None,
Expand Down
4 changes: 2 additions & 2 deletions tests/sentry/auth/test_principal.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,9 @@ def _is_request_user_type_check(node: ast.AST) -> bool:


# Lower these as callers move off. Exact, so the baseline can't drift back up.
REQUEST_USER_ID_BASELINE = 130
REQUEST_USER_ID_BASELINE = 129
REQUEST_USER_TYPE_CHECK_BASELINE = 29
REQUEST_USER_ALLOWLIST_BASELINE = 6
REQUEST_USER_ALLOWLIST_BASELINE = 5


def test_request_user_id_uses_only_go_down() -> None:
Expand Down
18 changes: 18 additions & 0 deletions tests/sentry/data_export/endpoints/test_data_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@
from sentry.data_export.endpoints.data_export import is_api_or_agent_request
from sentry.data_export.models import ExportedData
from sentry.data_export.writers import OutputMode
from sentry.models.apikey import ApiKey
from sentry.search.utils import parse_datetime_string
from sentry.silo.base import SiloMode
from sentry.testutils.cases import APITestCase
from sentry.testutils.helpers.datetime import before_now, freeze_time
from sentry.testutils.silo import assume_test_silo_mode
from sentry.utils import json
from sentry.utils.snuba import MAX_FIELDS

Expand Down Expand Up @@ -110,6 +113,21 @@ def test_authorization(self) -> None:
with self.feature("organizations:discover-query"):
self.get_error_response(self.org.slug, status_code=403, **modified_payload)

def test_api_key_cannot_export(self) -> None:
with assume_test_silo_mode(SiloMode.CONTROL):
key = ApiKey.objects.create(organization_id=self.org.id, scope_list=["event:read"])
self.client.logout()

response = self.client.post(
reverse(self.endpoint, args=[self.org.slug]),
self.make_payload("explore"),
format="json",
HTTP_AUTHORIZATION=self.create_basic_auth_header(key.key),
)

assert response.status_code == 401, response.content
assert not ExportedData.objects.exists()

def test_new_export(self) -> None:
"""
Ensures that a request to this endpoint returns a 201 status code
Expand Down
1 change: 0 additions & 1 deletion tools/mypy_helpers/request_user_allowlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@ src/sentry/api/bases/organizationmember.py
src/sentry/core/endpoints/organization_member_details.py
src/sentry/core/endpoints/organization_member_index.py
src/sentry/core/endpoints/organization_member_requests_invite_index.py
src/sentry/data_export/endpoints/data_export.py
src/sentry/issues/endpoints/group_integration_details.py
Loading