Skip to content

Commit 70e65f0

Browse files
committed
ref(typing): Let feature and search helpers take a service account
is_provider_enabled, the preprod quota checks, investigation action kinds' cannot_apply_reasons, parse_user_value and store_issue_last_defaults now take a RequestPrincipal. They only forward the caller to features.has(), ignore it, or already check has_user(), so this is type-only.
1 parent 3326f75 commit 70e65f0

8 files changed

Lines changed: 33 additions & 33 deletions

File tree

‎src/sentry/integrations/base.py‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,14 @@
4444
from sentry.utils.audit import create_audit_entry
4545

4646
if TYPE_CHECKING:
47-
from django.contrib.auth.models import AnonymousUser
4847
from django.utils.functional import _StrPromise
4948

49+
from sentry.auth.principal import RequestPrincipal
5050
from sentry.identity.services.identity.model import RpcIdentity
5151
from sentry.integrations.pipeline import IntegrationPipeline # noqa: F401
5252
from sentry.integrations.services.integration import RpcOrganizationIntegration
5353
from sentry.integrations.services.integration.model import RpcIntegration
5454
from sentry.models.organization import Organization
55-
from sentry.users.models.user import User
56-
from sentry.users.services.user import RpcUser
5755

5856

5957
logger = logging.getLogger(__name__)
@@ -623,7 +621,7 @@ def get_integration_types(provider: str) -> list[IntegrationDomain]:
623621
def is_provider_enabled(
624622
provider: IntegrationProvider,
625623
organization: Organization | RpcOrganization,
626-
actor: User | RpcUser | AnonymousUser | None = None,
624+
actor: RequestPrincipal | None = None,
627625
) -> bool:
628626
from sentry import features
629627

‎src/sentry/integrations/mixins/issues.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from typing import TYPE_CHECKING, Any, ClassVar
1010

1111
from sentry import features
12-
from sentry.auth.principal import has_user
12+
from sentry.auth.principal import RequestPrincipal, has_user
1313
from sentry.integrations.base import IntegrationInstallation
1414
from sentry.integrations.models.external_issue import ExternalIssue
1515
from sentry.integrations.models.integration import Integration
@@ -217,7 +217,7 @@ def get_persisted_user_default_config_fields(self):
217217
"""
218218
return []
219219

220-
def store_issue_last_defaults(self, project: Project, user: RpcUser | User, data):
220+
def store_issue_last_defaults(self, project: Project, user: RequestPrincipal, data):
221221
"""
222222
Stores the last used field defaults on a per-project basis. This
223223
accepts a dict of values that will be filtered to keys returned by

‎src/sentry/investigations/services/action_kinds/base.py‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
44
from collections.abc import Mapping, Sequence
55
from dataclasses import dataclass
66
from enum import StrEnum
7-
from typing import Any, Literal, NotRequired, TypedDict
7+
from typing import TYPE_CHECKING, Any, Literal, NotRequired, TypedDict
88

9-
from django.contrib.auth.models import AnonymousUser
109
from rest_framework.request import Request
1110

1211
from sentry.auth.access import Access
1312
from sentry.investigations.contracts import ActionPayloadSerializer
1413
from sentry.investigations.models import InvestigationOrchestrationRun
1514
from sentry.notebooks.models import Notebook, NotebookActionRequest
16-
from sentry.users.models.user import User
17-
from sentry.users.services.user.model import RpcUser
15+
16+
if TYPE_CHECKING:
17+
from sentry.auth.principal import RequestPrincipal
1818

1919

2020
class CannotApplyReason(StrEnum):
@@ -120,7 +120,7 @@ def cannot_apply_reasons(
120120
*,
121121
investigations: dict[int, Notebook],
122122
access: Access,
123-
user: User | RpcUser | AnonymousUser,
123+
user: RequestPrincipal,
124124
) -> dict[int, CannotApplyReason | None]:
125125
"""For each suggested request, why the viewer can't apply it, or None if they can."""
126126
return {item.id: CannotApplyReason.UNSUPPORTED_ACTION for item in action_requests}

‎src/sentry/investigations/services/action_kinds/connect_telemetry.py‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
from __future__ import annotations
22

33
from collections.abc import Sequence
4-
from typing import Literal, TypedDict
4+
from typing import TYPE_CHECKING, Literal, TypedDict
55

6-
from django.contrib.auth.models import AnonymousUser
76
from django.db import router, transaction
87
from django.db.models import QuerySet
98
from rest_framework import serializers
@@ -21,8 +20,9 @@
2120
from sentry.models.organization import Organization
2221
from sentry.notebooks.models import Notebook, NotebookActionRequest, NotebookActionRequestState
2322
from sentry.seer.agent.monitoring_providers import org_monitoring_provider_registry
24-
from sentry.users.models.user import User
25-
from sentry.users.services.user.model import RpcUser
23+
24+
if TYPE_CHECKING:
25+
from sentry.auth.principal import RequestPrincipal
2626

2727
CONNECT_TELEMETRY_ACTION = "connect_telemetry"
2828
TelemetryProvider = Literal["datadog", "gcp"]
@@ -83,7 +83,7 @@ def cannot_apply_reasons(
8383
*,
8484
investigations: dict[int, Notebook],
8585
access: Access,
86-
user: User | RpcUser | AnonymousUser,
86+
user: RequestPrincipal,
8787
) -> dict[int, CannotApplyReason | None]:
8888
can_install = access.has_scope(_INSTALL_SCOPE)
8989
reasons: dict[int, CannotApplyReason | None] = {}

‎src/sentry/investigations/services/action_kinds/update_detector.py‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
from collections import defaultdict
44
from collections.abc import Collection, Mapping, Sequence
55
from dataclasses import dataclass
6-
from typing import Any, Literal, TypedDict, cast
6+
from typing import TYPE_CHECKING, Any, Literal, TypedDict, cast
77

8-
from django.contrib.auth.models import AnonymousUser
98
from django.db import router, transaction
109
from rest_framework import serializers
1110

@@ -42,8 +41,6 @@
4241
from sentry.notebooks.contracts import StrictContractSerializer
4342
from sentry.notebooks.models import Notebook, NotebookActionRequest
4443
from sentry.snuba.models import SnubaQuery
45-
from sentry.users.models.user import User
46-
from sentry.users.services.user.model import RpcUser
4744
from sentry.workflow_engine.endpoints.organization_detector_details import (
4845
check_metric_detector_allowed,
4946
)
@@ -56,6 +53,9 @@
5653
from sentry.workflow_engine.models.detector import DetectorQuerySet
5754
from sentry.workflow_engine.types import DetectorPriorityLevel
5855

56+
if TYPE_CHECKING:
57+
from sentry.auth.principal import RequestPrincipal
58+
5959
UPDATE_DETECTOR_ACTION = "update_detector"
6060

6161

@@ -404,7 +404,7 @@ def cannot_apply_reasons(
404404
*,
405405
investigations: dict[int, Notebook],
406406
access: Access,
407-
user: User | RpcUser | AnonymousUser,
407+
user: RequestPrincipal,
408408
) -> dict[int, CannotApplyReason | None]:
409409
source_detector_ids = {
410410
investigation_id: source_detector_id(source)

‎src/sentry/preprod/quotas.py‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
from collections.abc import Callable
55
from datetime import datetime, timedelta
66
from enum import Enum
7-
from typing import Any
7+
from typing import TYPE_CHECKING, Any
88

99
import sentry_sdk
10-
from django.contrib.auth.models import AnonymousUser
1110
from django.utils import timezone
1211

1312
from sentry import features, quotas
@@ -16,7 +15,9 @@
1615
from sentry.models.organization import Organization
1716
from sentry.preprod.artifact_search import artifact_matches_query
1817
from sentry.preprod.models import PreprodArtifact
19-
from sentry.users.models.user import User
18+
19+
if TYPE_CHECKING:
20+
from sentry.auth.principal import RequestPrincipal
2021

2122
logger = logging.getLogger(__name__)
2223

@@ -45,7 +46,7 @@ def get_size_retention_cutoff(organization: Organization) -> datetime:
4546
DISTRIBUTION_ENABLED_QUERY_KEY = "sentry:preprod_distribution_enabled_query"
4647

4748

48-
def has_size_quota(organization: Organization, actor: User | AnonymousUser | None = None) -> bool:
49+
def has_size_quota(organization: Organization, actor: RequestPrincipal | None = None) -> bool:
4950
result = quotas.backend.has_usage_quota(organization.id, DataCategory.SIZE_ANALYSIS)
5051
logger.info(
5152
"has_size_quota",
@@ -55,7 +56,7 @@ def has_size_quota(organization: Organization, actor: User | AnonymousUser | Non
5556

5657

5758
def has_installable_quota(
58-
organization: Organization, actor: User | AnonymousUser | None = None
59+
organization: Organization, actor: RequestPrincipal | None = None
5960
) -> bool:
6061
if not features.has(
6162
"organizations:preprod-enforce-distribution-quota", organization, actor=actor

‎src/sentry/search/utils.py‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from collections.abc import Callable, Sequence
55
from datetime import datetime, timedelta, timezone
66
from enum import Enum
7-
from typing import Any, Optional
7+
from typing import TYPE_CHECKING, Any, Optional
88

99
from django.contrib.auth.models import AnonymousUser
1010
from django.db import DataError, connections, router
@@ -33,6 +33,9 @@
3333
from sentry.utils.validators import is_event_id_or_list as _is_event_id_or_list
3434
from sentry.utils.validators import is_span_id_or_list as _is_span_id_or_list
3535

36+
if TYPE_CHECKING:
37+
from sentry.auth.principal import RequestPrincipal
38+
3639

3740
class InvalidQuery(Exception):
3841
pass
@@ -352,7 +355,7 @@ def parse_actor_or_none_value(
352355
_HACKY_INVALID_USER = RpcUser(id=0)
353356

354357

355-
def parse_user_value(value: str, user: User | RpcUser | AnonymousUser) -> RpcUser:
358+
def parse_user_value(value: str, user: RequestPrincipal) -> RpcUser:
356359
if value == "me":
357360
if isinstance(user, User):
358361
return serialize_rpc_user(user)

‎tests/sentry/investigations/test_contracts.py‎

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66

77
import orjson
88
import pytest
9-
from django.contrib.auth.models import AnonymousUser
109

1110
from sentry.auth.access import Access
11+
from sentry.auth.principal import RequestPrincipal
1212
from sentry.db.models.fields.bounded import I32_MAX, I64_MAX
1313
from sentry.investigations.contracts import (
1414
MAX_PROJECTION_BYTES,
@@ -32,8 +32,6 @@
3232
CannotApplyReason,
3333
)
3434
from sentry.notebooks.models import Notebook, NotebookActionRequest
35-
from sentry.users.models.user import User
36-
from sentry.users.services.user.model import RpcUser
3735
from sentry.utils import json
3836
from tests.sentry.notebooks.test_contracts import golden_payload
3937

@@ -536,7 +534,7 @@ def __init__(self) -> None:
536534
# The requests after_upsert ran for, in order.
537535
self.upserted: list[NotebookActionRequest] = []
538536
# The arguments from each cannot_apply_reasons call.
539-
self.checked: list[tuple[list[int], list[int], Access, User | RpcUser | AnonymousUser]] = []
537+
self.checked: list[tuple[list[int], list[int], Access, RequestPrincipal]] = []
540538
# Which of check_remote, check and apply ran, in order.
541539
self.calls: list[str] = []
542540
# What check and apply raise, if anything.
@@ -557,7 +555,7 @@ def cannot_apply_reasons(
557555
*,
558556
investigations: dict[int, Notebook],
559557
access: Access,
560-
user: User | RpcUser | AnonymousUser,
558+
user: RequestPrincipal,
561559
) -> dict[int, CannotApplyReason | None]:
562560
self.checked.append(
563561
([item.id for item in action_requests], sorted(investigations), access, user)

0 commit comments

Comments
 (0)