diff --git a/src/sentry/identity/slack/provider.py b/src/sentry/identity/slack/provider.py index 05aabaa99c291b..4cac4c4a3f4720 100644 --- a/src/sentry/identity/slack/provider.py +++ b/src/sentry/identity/slack/provider.py @@ -1,11 +1,12 @@ from sentry import options from sentry.identity.oauth2 import OAuth2CallbackView, OAuth2LoginView, OAuth2Provider from sentry.identity.pipeline import IdentityPipeline +from sentry.integrations.types import IntegrationProviderSlug from sentry.pipeline.views.base import PipelineView class SlackIdentityProvider(OAuth2Provider): - key = "slack" + key = IntegrationProviderSlug.SLACK.value name = "Slack" # This identity provider is used for authorizing the Slack application @@ -61,7 +62,7 @@ def build_identity(self, data): data = data["data"] return { - "type": "slack", + "type": IntegrationProviderSlug.SLACK.value, # TODO(epurkhiser): See note above "id": data["user"]["id"], "email": data["user"]["email"], diff --git a/src/sentry/integrations/messaging/linkage.py b/src/sentry/integrations/messaging/linkage.py index 722b1282475268..8b5a3901fb4ff2 100644 --- a/src/sentry/integrations/messaging/linkage.py +++ b/src/sentry/integrations/messaging/linkage.py @@ -20,7 +20,11 @@ from sentry.integrations.models.external_actor import ExternalActor from sentry.integrations.models.integration import Integration from sentry.integrations.services.integration import RpcIntegration, integration_service -from sentry.integrations.types import ExternalProviderEnum, ExternalProviders +from sentry.integrations.types import ( + ExternalProviderEnum, + ExternalProviders, + IntegrationProviderSlug, +) from sentry.integrations.utils.identities import get_identity_or_404 from sentry.models.organizationmember import OrganizationMember from sentry.models.team import Team @@ -460,7 +464,8 @@ def execute( logger_params["team_id"] = team.id idp = identity_service.get_provider( - provider_type="slack", provider_ext_id=integration.external_id + provider_type=IntegrationProviderSlug.SLACK.value, + provider_ext_id=integration.external_id, ) logger_params["provider_ext_id"] = integration.external_id if idp is None: diff --git a/src/sentry/integrations/slack/actions/notification.py b/src/sentry/integrations/slack/actions/notification.py index 7d660d52173ee0..a7c938cb168b2f 100644 --- a/src/sentry/integrations/slack/actions/notification.py +++ b/src/sentry/integrations/slack/actions/notification.py @@ -32,6 +32,7 @@ from sentry.integrations.slack.spec import SlackMessagingSpec from sentry.integrations.slack.utils.channel import SlackChannelIdData, get_channel_id from sentry.integrations.slack.utils.threads import NotificationActionThreadUtils +from sentry.integrations.types import IntegrationProviderSlug from sentry.integrations.utils.metrics import EventLifecycle from sentry.issues.grouptype import GroupCategory from sentry.models.options.organization_option import OrganizationOption @@ -51,7 +52,7 @@ class SlackNotifyServiceAction(IntegrationEventAction): id = "sentry.integrations.slack.notify_action.SlackNotifyServiceAction" prompt = "Send a Slack notification" - provider = "slack" + provider = IntegrationProviderSlug.SLACK.value integration_key = "workspace" label = "Send a notification to the {workspace} Slack workspace to {channel} (optionally, an ID: {channel_id}) and show tags {tags} and notes {notes} in notification" diff --git a/src/sentry/integrations/slack/integration.py b/src/sentry/integrations/slack/integration.py index 8744c7a07fa9d9..74fe2f0f0c23b1 100644 --- a/src/sentry/integrations/slack/integration.py +++ b/src/sentry/integrations/slack/integration.py @@ -132,7 +132,7 @@ class SlackIntegrationProvider(IntegrationProvider): def _identity_pipeline_view(self) -> PipelineView[IntegrationPipeline]: return NestedPipelineView( bind_key="identity", - provider_key="slack", + provider_key=IntegrationProviderSlug.SLACK.value, pipeline_cls=IdentityPipeline, config={ "oauth_scopes": self.identity_oauth_scopes, @@ -184,7 +184,7 @@ def build_integration(self, state: Mapping[str, Any]) -> IntegrationData: "external_id": team_id, "metadata": metadata, "user_identity": { - "type": "slack", + "type": IntegrationProviderSlug.SLACK.value, "external_id": user_id_slack, "scopes": [], "data": {}, diff --git a/src/sentry/integrations/slack/requests/base.py b/src/sentry/integrations/slack/requests/base.py index 2b7bf34ea9f2b8..b9462371b12c40 100644 --- a/src/sentry/integrations/slack/requests/base.py +++ b/src/sentry/integrations/slack/requests/base.py @@ -15,6 +15,7 @@ from sentry.identity.services.identity.model import RpcIdentityProvider from sentry.integrations.messaging.commands import CommandInput from sentry.integrations.services.integration import RpcIntegration, integration_service +from sentry.integrations.types import IntegrationProviderSlug from sentry.users.services.user import RpcUser from sentry.users.services.user.service import user_service from sentry.utils.safe import get_path @@ -99,7 +100,7 @@ def _get_context(self): except Exception: pass context = integration_service.get_integration_identity_context( - integration_provider="slack", + integration_provider=IntegrationProviderSlug.SLACK.value, integration_external_id=team_id, identity_external_id=user_id, identity_provider_external_id=team_id, @@ -162,7 +163,7 @@ def get_identity(self) -> RpcIdentity | None: if self._provider is None: self._provider = identity_service.get_provider( - provider_type="slack", provider_ext_id=self.team_id + provider_type=IntegrationProviderSlug.SLACK.value, provider_ext_id=self.team_id ) if self._provider is not None: @@ -225,7 +226,9 @@ def _check_verification_token(self, verification_token: str) -> bool: def validate_integration(self) -> None: if not self._integration: self._integration = integration_service.get_integration( - provider="slack", external_id=self.team_id, status=ObjectStatus.ACTIVE + provider=IntegrationProviderSlug.SLACK.value, + external_id=self.team_id, + status=ObjectStatus.ACTIVE, ) if not self._integration: diff --git a/src/sentry/integrations/slack/sdk_client.py b/src/sentry/integrations/slack/sdk_client.py index 80419fd5b6e96b..93e4f26ec24915 100644 --- a/src/sentry/integrations/slack/sdk_client.py +++ b/src/sentry/integrations/slack/sdk_client.py @@ -11,6 +11,7 @@ from sentry.integrations.models import Integration from sentry.integrations.services.integration import integration_service from sentry.integrations.services.integration.model import RpcIntegration +from sentry.integrations.types import IntegrationProviderSlug from sentry.silo.base import SiloMode from sentry.utils import metrics @@ -32,7 +33,7 @@ def track_response_data(response: SlackResponse, method: str, error: str | None ) extra = { - "integration": "slack", + "integration": IntegrationProviderSlug.SLACK.value, "status_string": str(code), "error": error, "method": method, diff --git a/src/sentry/integrations/slack/spec.py b/src/sentry/integrations/slack/spec.py index 120bb39188f781..4ba44dfc233c39 100644 --- a/src/sentry/integrations/slack/spec.py +++ b/src/sentry/integrations/slack/spec.py @@ -12,6 +12,7 @@ MessagingIdentityLinkViewSet, MessagingIntegrationSpec, ) +from sentry.integrations.types import IntegrationProviderSlug from sentry.models.organization import Organization from sentry.notifications.models.notificationaction import ActionService from sentry.rules.actions import IntegrationEventAction @@ -20,7 +21,7 @@ class SlackMessagingSpec(MessagingIntegrationSpec): @property def provider_slug(self) -> str: - return "slack" + return IntegrationProviderSlug.SLACK.value @property def action_service(self) -> ActionService: diff --git a/src/sentry/integrations/slack/tasks/find_channel_id_for_alert_rule.py b/src/sentry/integrations/slack/tasks/find_channel_id_for_alert_rule.py index 33232060b51c96..3b8f6a85776a95 100644 --- a/src/sentry/integrations/slack/tasks/find_channel_id_for_alert_rule.py +++ b/src/sentry/integrations/slack/tasks/find_channel_id_for_alert_rule.py @@ -15,6 +15,7 @@ from sentry.incidents.serializers import AlertRuleSerializer from sentry.integrations.slack.utils.constants import SLACK_RATE_LIMITED_MESSAGE from sentry.integrations.slack.utils.rule_status import RedisRuleStatus +from sentry.integrations.types import IntegrationProviderSlug from sentry.models.organization import Organization from sentry.shared_integrations.exceptions import ApiRateLimitedError from sentry.silo.base import SiloMode @@ -85,7 +86,7 @@ def find_channel_id_for_alert_rule( for trigger in data["triggers"]: for action in trigger["actions"]: - if action["type"] == "slack": + if action["type"] == IntegrationProviderSlug.SLACK.value: if action["targetIdentifier"] in mapped_ids: action["input_channel_id"] = mapped_ids[action["targetIdentifier"]] # This will conflict within the CamelCaseSerializer below. diff --git a/src/sentry/integrations/slack/tasks/find_channel_id_for_rule.py b/src/sentry/integrations/slack/tasks/find_channel_id_for_rule.py index 598371c900632a..29e836d4cf58b7 100644 --- a/src/sentry/integrations/slack/tasks/find_channel_id_for_rule.py +++ b/src/sentry/integrations/slack/tasks/find_channel_id_for_rule.py @@ -10,6 +10,7 @@ ) from sentry.integrations.slack.utils.constants import SLACK_RATE_LIMITED_MESSAGE from sentry.integrations.slack.utils.rule_status import RedisRuleStatus +from sentry.integrations.types import IntegrationProviderSlug from sentry.models.project import Project from sentry.models.rule import Rule, RuleActivity, RuleActivityType from sentry.projects.project_rules.creator import ProjectRuleCreator @@ -60,7 +61,9 @@ def find_channel_id_for_rule( break integrations = integration_service.get_integrations( - organization_id=organization.id, providers=["slack"], integration_ids=[integration_id] + organization_id=organization.id, + providers=[IntegrationProviderSlug.SLACK.value], + integration_ids=[integration_id], ) if not integrations: redis_rule_status.set_value("failed") diff --git a/src/sentry/integrations/slack/webhooks/action.py b/src/sentry/integrations/slack/webhooks/action.py index b99c84c9dece46..33b1f859d6fafd 100644 --- a/src/sentry/integrations/slack/webhooks/action.py +++ b/src/sentry/integrations/slack/webhooks/action.py @@ -37,7 +37,7 @@ from sentry.integrations.slack.sdk_client import SlackSdkClient from sentry.integrations.slack.spec import SlackMessagingSpec from sentry.integrations.slack.utils.errors import MODAL_NOT_FOUND, unpack_slack_api_error -from sentry.integrations.types import ExternalProviderEnum +from sentry.integrations.types import ExternalProviderEnum, IntegrationProviderSlug from sentry.integrations.utils.scope import bind_org_context_from_integration from sentry.models.activity import ActivityIntegration from sentry.models.group import Group @@ -702,7 +702,9 @@ def handle_member_approval(self, slack_request: SlackActionRequest, action: str) original_status = InviteStatus(member.invite_status) try: if action == "approve_member": - member.approve_member_invitation(identity_user, referrer="slack") + member.approve_member_invitation( + identity_user, referrer=IntegrationProviderSlug.SLACK.value + ) else: member.reject_member_invitation(identity_user) except Exception: diff --git a/src/sentry/middleware/integrations/tasks.py b/src/sentry/middleware/integrations/tasks.py index 735ec76af1339c..48d5c6f6f63fa0 100644 --- a/src/sentry/middleware/integrations/tasks.py +++ b/src/sentry/middleware/integrations/tasks.py @@ -107,7 +107,7 @@ def _forward_response(self, result: _AsyncResult) -> Response | None: class _AsyncSlackDispatcher(_AsyncRegionDispatcher): @property def log_code(self) -> str: - return "slack" + return IntegrationProviderSlug.SLACK.value def unpack_payload(self, response: Response) -> Any: return orjson.loads(response.content) diff --git a/src/sentry/notifications/notifications/digest.py b/src/sentry/notifications/notifications/digest.py index 38d38972c6a1ce..90db3abf486d74 100644 --- a/src/sentry/notifications/notifications/digest.py +++ b/src/sentry/notifications/notifications/digest.py @@ -16,7 +16,7 @@ should_get_personalized_digests, ) from sentry.eventstore.models import Event -from sentry.integrations.types import ExternalProviders +from sentry.integrations.types import ExternalProviders, IntegrationProviderSlug from sentry.notifications.notifications.base import ProjectNotification from sentry.notifications.notify import notify from sentry.notifications.types import ActionTargetType, FallthroughChoiceType, UnsubscribeContext @@ -151,7 +151,7 @@ def build_context( "user_counts": digest.user_counts, "has_alert_integration": has_alert_integration(project), "project": project, - "slack_link": get_integration_link(organization, "slack"), + "slack_link": get_integration_link(organization, IntegrationProviderSlug.SLACK.value), "rules_details": {rule.id: rule for rule in rule_details}, "link_params_for_rule": get_email_link_extra_params( "digest_email", diff --git a/src/sentry/notifications/notifications/rules.py b/src/sentry/notifications/notifications/rules.py index a0739f303b0dbd..7b1d7f139fea3d 100644 --- a/src/sentry/notifications/notifications/rules.py +++ b/src/sentry/notifications/notifications/rules.py @@ -10,7 +10,11 @@ from sentry.db.models import Model from sentry.eventstore.models import GroupEvent from sentry.integrations.issue_alert_image_builder import IssueAlertImageBuilder -from sentry.integrations.types import ExternalProviderEnum, ExternalProviders +from sentry.integrations.types import ( + ExternalProviderEnum, + ExternalProviders, + IntegrationProviderSlug, +) from sentry.issues.grouptype import ( GROUP_CATEGORIES_CUSTOM_EMAIL, GroupCategory, @@ -194,7 +198,9 @@ def get_context(self) -> MutableMapping[str, Any]: "enhanced_privacy": enhanced_privacy, "commits": get_commits(self.project, self.event), "environment": environment, - "slack_link": get_integration_link(self.organization, "slack", self.notification_uuid), + "slack_link": get_integration_link( + self.organization, IntegrationProviderSlug.SLACK.value, self.notification_uuid + ), "notification_reason": notification_reason, "notification_settings_link": absolute_uri( f"/settings/account/notifications/alerts/{sentry_query_params}" diff --git a/src/sentry/users/models/identity.py b/src/sentry/users/models/identity.py index 0a727d10656200..02a2c9c35bd73d 100644 --- a/src/sentry/users/models/identity.py +++ b/src/sentry/users/models/identity.py @@ -20,7 +20,7 @@ ) from sentry.db.models.fields.jsonfield import JSONField from sentry.db.models.manager.base import BaseManager -from sentry.integrations.types import ExternalProviders +from sentry.integrations.types import ExternalProviders, IntegrationProviderSlug from sentry.users.services.user import RpcUser if TYPE_CHECKING: @@ -108,7 +108,7 @@ def link_identity( analytics.record( "integrations.identity_linked", - provider="slack", + provider=IntegrationProviderSlug.SLACK.value, # Note that prior to circa March 2023 this was user.actor_id. It changed # when actor ids were no longer stable between regions for the same user actor_id=user.id, diff --git a/src/sentry/web/frontend/debug/debug_organization_integration_request.py b/src/sentry/web/frontend/debug/debug_organization_integration_request.py index 285617e6add453..0ccc34143ff058 100644 --- a/src/sentry/web/frontend/debug/debug_organization_integration_request.py +++ b/src/sentry/web/frontend/debug/debug_organization_integration_request.py @@ -1,6 +1,7 @@ from django.http import HttpRequest, HttpResponse from django.views.generic import View +from sentry.integrations.types import IntegrationProviderSlug from sentry.models.organization import Organization from sentry.models.organizationmember import OrganizationMember from sentry.notifications.notifications.organization_request.integration_request import ( @@ -22,7 +23,7 @@ def get(self, request: HttpRequest) -> HttpResponse: org, requester, provider_type="first_party", - provider_slug="slack", + provider_slug=IntegrationProviderSlug.SLACK.value, provider_name="Slack", )