From 6b96e8f0c484876f8d5cf59ed1cd9d84d5d860a1 Mon Sep 17 00:00:00 2001 From: Alexander Tarasov Date: Fri, 13 Sep 2024 16:22:40 +0200 Subject: [PATCH] cleanup: delete unused social-identities endpoints (#77231) The last usage of `/social-identities/` endpoints was removed in https://github.com/getsentry/sentry/pull/29230, 3 years ago. --- .../endpoints/user_social_identities_index.py | 30 ---------- .../endpoints/user_social_identity_details.py | 60 ------------------- src/sentry/api/urls.py | 12 ---- .../api_ownership_allowlist_dont_modify.py | 2 - ...pi_publish_status_allowlist_dont_modify.py | 2 - .../api_pagination_allowlist_do_not_modify.py | 1 - .../test_user_social_identities_index.py | 19 ------ .../test_user_social_identity_details.py | 24 -------- 8 files changed, 150 deletions(-) delete mode 100644 src/sentry/api/endpoints/user_social_identities_index.py delete mode 100644 src/sentry/api/endpoints/user_social_identity_details.py delete mode 100644 tests/sentry/api/endpoints/test_user_social_identities_index.py delete mode 100644 tests/sentry/api/endpoints/test_user_social_identity_details.py diff --git a/src/sentry/api/endpoints/user_social_identities_index.py b/src/sentry/api/endpoints/user_social_identities_index.py deleted file mode 100644 index 823ae8a67a70f..0000000000000 --- a/src/sentry/api/endpoints/user_social_identities_index.py +++ /dev/null @@ -1,30 +0,0 @@ -from rest_framework.request import Request -from rest_framework.response import Response - -from sentry.api.api_owners import ApiOwner -from sentry.api.api_publish_status import ApiPublishStatus -from sentry.api.base import control_silo_endpoint -from sentry.api.bases.user import UserEndpoint -from sentry.api.serializers import serialize -from social_auth.models import UserSocialAuth - - -@control_silo_endpoint -class UserSocialIdentitiesIndexEndpoint(UserEndpoint): - publish_status = { - "GET": ApiPublishStatus.PRIVATE, - } - owner = ApiOwner.ENTERPRISE - - def get(self, request: Request, user) -> Response: - """ - List Account's Identities - ````````````````````````` - - List an account's associated identities (e.g. github when trying to add a repo) - - :auth: required - """ - - identity_list = list(UserSocialAuth.objects.filter(user=user)) - return Response(serialize(identity_list)) diff --git a/src/sentry/api/endpoints/user_social_identity_details.py b/src/sentry/api/endpoints/user_social_identity_details.py deleted file mode 100644 index a9932ba2c2917..0000000000000 --- a/src/sentry/api/endpoints/user_social_identity_details.py +++ /dev/null @@ -1,60 +0,0 @@ -import logging - -from rest_framework.request import Request -from rest_framework.response import Response - -from sentry.api.api_owners import ApiOwner -from sentry.api.api_publish_status import ApiPublishStatus -from sentry.api.base import control_silo_endpoint -from sentry.api.bases.user import UserEndpoint -from social_auth.backends import get_backend -from social_auth.models import UserSocialAuth - -logger = logging.getLogger("sentry.accounts") - - -@control_silo_endpoint -class UserSocialIdentityDetailsEndpoint(UserEndpoint): - publish_status = { - "DELETE": ApiPublishStatus.PRIVATE, - } - owner = ApiOwner.ENTERPRISE - - def delete(self, request: Request, user, identity_id) -> Response: - """ - Disconnect a Identity from Account - ``````````````````````````````````````````````````````` - - Disconnects a social auth identity from a sentry account - - :pparam string identity_id: identity id - :auth: required - """ - - try: - auth = UserSocialAuth.objects.get(id=identity_id) - except UserSocialAuth.DoesNotExist: - return Response(status=404) - - backend = get_backend(auth.provider, request, "/") - if backend is None: - raise Exception(f"Backend was not found for request: {auth.provider}") - - # stop this from bubbling up errors to social-auth's middleware - # XXX(dcramer): IM SO MAD ABOUT THIS - backend.disconnect(user, identity_id) - - # XXX(dcramer): we experienced an issue where the identity still existed, - # and given that this is a cheap query, lets error hard in that case - assert not UserSocialAuth.objects.filter(user=user, id=identity_id).exists() - - logger.info( - "user.identity.disconnect", - extra={ - "user_id": user.id, - "ip_address": request.META["REMOTE_ADDR"], - "usersocialauth_id": identity_id, - }, - ) - - return Response(status=204) diff --git a/src/sentry/api/urls.py b/src/sentry/api/urls.py index 48a5588bac663..b8268d3ad3d63 100644 --- a/src/sentry/api/urls.py +++ b/src/sentry/api/urls.py @@ -668,8 +668,6 @@ ) from .endpoints.user_organizationintegrations import UserOrganizationIntegrationsEndpoint from .endpoints.user_organizations import UserOrganizationsEndpoint -from .endpoints.user_social_identities_index import UserSocialIdentitiesIndexEndpoint -from .endpoints.user_social_identity_details import UserSocialIdentityDetailsEndpoint from .endpoints.user_subscriptions import UserSubscriptionsEndpoint __all__ = ("urlpatterns",) @@ -1091,16 +1089,6 @@ def create_group_urls(name_prefix: str) -> list[URLPattern | URLResolver]: UserUserRoleDetailsEndpoint.as_view(), name="sentry-api-0-user-userrole-details", ), - re_path( - r"^(?P[^\/]+)/social-identities/$", - UserSocialIdentitiesIndexEndpoint.as_view(), - name="sentry-api-0-user-social-identities-index", - ), - re_path( - r"^(?P[^\/]+)/social-identities/(?P[^\/]+)/$", - UserSocialIdentityDetailsEndpoint.as_view(), - name="sentry-api-0-user-social-identity-details", - ), re_path( r"^(?P[^\/]+)/subscriptions/$", UserSubscriptionsEndpoint.as_view(), diff --git a/src/sentry/apidocs/api_ownership_allowlist_dont_modify.py b/src/sentry/apidocs/api_ownership_allowlist_dont_modify.py index 241113812e0be..94ba8c7342e7c 100644 --- a/src/sentry/apidocs/api_ownership_allowlist_dont_modify.py +++ b/src/sentry/apidocs/api_ownership_allowlist_dont_modify.py @@ -9,7 +9,6 @@ "/api/0/organizations/{organization_id_or_slug}/relay_usage/", "/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/events/{event_id}/owners/", "/api/0/organizations/{organization_id_or_slug}/data-export/{data_export_id}/", - "/api/0/users/{user_id}/social-identities/{identity_id}/", "/api/0/users/{user_id}/identities/", "/api/0/teams/{organization_id_or_slug}/{team_id_or_slug}/external-teams/{external_team_id}/", "/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/artifact-lookup/", @@ -91,7 +90,6 @@ "/api/0/sentry-apps-stats/", "/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/teams/{team_id_or_slug}/", "/api/0/monitors/{monitor_id_or_slug}/checkins/", - "/api/0/users/{user_id}/social-identities/", "/api/0/organizations/{organization_id_or_slug}/discover/saved/", "/api/0/organizations/{organization_id_or_slug}/integration-requests/", "/extensions/vsts/issue-updated/", diff --git a/src/sentry/apidocs/api_publish_status_allowlist_dont_modify.py b/src/sentry/apidocs/api_publish_status_allowlist_dont_modify.py index e75856adddf30..553132be5907b 100644 --- a/src/sentry/apidocs/api_publish_status_allowlist_dont_modify.py +++ b/src/sentry/apidocs/api_publish_status_allowlist_dont_modify.py @@ -804,8 +804,6 @@ "/api/0/users/{user_id}/permissions/{permission_name}/": {"DELETE", "GET", "POST"}, "/api/0/users/{user_id}/roles/": {"GET"}, "/api/0/users/{user_id}/roles/{role_name}/": {"DELETE", "GET", "POST"}, - "/api/0/users/{user_id}/social-identities/": {"GET"}, - "/api/0/users/{user_id}/social-identities/{identity_id}/": {"DELETE"}, "/api/0/users/{user_id}/subscriptions/": {"GET", "PUT", "POST"}, "/api/0/users/{user_id}/organization-integrations/": {"GET"}, "/api/0/users/{user_id}/user-identities/": {"GET"}, diff --git a/src/sentry/conf/api_pagination_allowlist_do_not_modify.py b/src/sentry/conf/api_pagination_allowlist_do_not_modify.py index 5d1919a9b16dd..d3ad9bce77bc6 100644 --- a/src/sentry/conf/api_pagination_allowlist_do_not_modify.py +++ b/src/sentry/conf/api_pagination_allowlist_do_not_modify.py @@ -104,7 +104,6 @@ "UserPermissionsConfigEndpoint", "UserPermissionsEndpoint", "UserRolesEndpoint", - "UserSocialIdentitiesIndexEndpoint", "UserSubscriptionsEndpoint", "UserUserRolesEndpoint", "VstsSearchEndpoint", diff --git a/tests/sentry/api/endpoints/test_user_social_identities_index.py b/tests/sentry/api/endpoints/test_user_social_identities_index.py deleted file mode 100644 index 9ab40b3e96f72..0000000000000 --- a/tests/sentry/api/endpoints/test_user_social_identities_index.py +++ /dev/null @@ -1,19 +0,0 @@ -from sentry.testutils.cases import APITestCase -from sentry.testutils.silo import control_silo_test -from social_auth.models import UserSocialAuth - - -@control_silo_test -class UserSocialIdentitiesIndexTest(APITestCase): - endpoint = "sentry-api-0-user-social-identities-index" - - def setUp(self): - super().setUp() - self.login_as(self.user) - - def test_simple(self): - UserSocialAuth.create_social_auth(self.user, "1234", "github") - - response = self.get_success_response(self.user.id) - assert len(response.data) == 1 - assert response.data[0]["provider"] == "github" diff --git a/tests/sentry/api/endpoints/test_user_social_identity_details.py b/tests/sentry/api/endpoints/test_user_social_identity_details.py deleted file mode 100644 index 085dad0f4252e..0000000000000 --- a/tests/sentry/api/endpoints/test_user_social_identity_details.py +++ /dev/null @@ -1,24 +0,0 @@ -from sentry.testutils.cases import APITestCase -from sentry.testutils.silo import control_silo_test -from social_auth.models import UserSocialAuth - - -@control_silo_test -class UserSocialIdentityDetailsEndpointTest(APITestCase): - endpoint = "sentry-api-0-user-social-identity-details" - method = "delete" - - def setUp(self): - self.login_as(self.user) - - def test_can_disconnect(self): - auth = UserSocialAuth.create_social_auth(self.user, "1234", "github") - - with self.settings(GITHUB_APP_ID="app-id", GITHUB_API_SECRET="secret"): - self.get_success_response(self.user.id, auth.id, status_code=204) - assert not len(UserSocialAuth.objects.filter(user=self.user)) - - def test_disconnect_id_not_found(self): - with self.settings(GITHUB_APP_ID="app-id", GITHUB_API_SECRET="secret"): - self.get_error_response(self.user.id, 999, status_code=404) - assert not len(UserSocialAuth.objects.filter(user=self.user))