Skip to content

Commit cae04f1

Browse files
authored
chore: Remove role related methods (#52826)
Now that they are unused we can remove the role switching logic.
1 parent 22cb937 commit cae04f1

File tree

2 files changed

+0
-146
lines changed

2 files changed

+0
-146
lines changed

src/sentry/db/postgres/roles.py

Lines changed: 0 additions & 32 deletions
This file was deleted.

src/sentry/testutils/silo.py

Lines changed: 0 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,15 @@
33
import functools
44
import inspect
55
import re
6-
import sys
76
from contextlib import contextmanager
87
from typing import Any, Callable, Dict, Iterable, List, MutableMapping, MutableSet, Set, Tuple, Type
98
from unittest import TestCase
109

1110
import pytest
1211
from django.apps import apps
1312
from django.conf import settings
14-
from django.db import connections, router
1513
from django.db.models import Model
1614
from django.db.models.fields.related import RelatedField
17-
from django.db.models.signals import post_migrate
18-
from django.db.transaction import get_connection
1915
from django.test import override_settings
2016

2117
from sentry import deletions
@@ -195,116 +191,6 @@ def assume_test_silo_mode(desired_silo: SiloMode) -> Any:
195191
yield
196192

197193

198-
def reset_test_role(role: str, using: str, create_role: bool) -> None:
199-
# Deprecated, will remove once getsentry is updated.
200-
connection_names = [conn.alias for conn in connections.all()]
201-
202-
if create_role:
203-
role_exists = False
204-
with get_connection(using).cursor() as connection:
205-
connection.execute("SELECT 1 FROM pg_roles WHERE rolname = %s", [role])
206-
role_exists = connection.fetchone()
207-
208-
if role_exists:
209-
# Drop role permissions on each connection, or we can't drop the role.
210-
for alias in connection_names:
211-
with get_connection(alias).cursor() as conn:
212-
conn.execute(f"REASSIGN OWNED BY {role} TO postgres")
213-
conn.execute(f"DROP OWNED BY {role} CASCADE")
214-
215-
# Drop and re-create the role as required.
216-
with get_connection(using).cursor() as conn:
217-
conn.execute(f"DROP ROLE {role}")
218-
219-
with get_connection(using).cursor() as conn:
220-
conn.execute(f"CREATE ROLE {role}")
221-
222-
# Create permissions on the current connection as we'll build up permissions incrementally.
223-
with get_connection(using).cursor() as conn:
224-
conn.execute(f"GRANT USAGE ON SCHEMA public TO {role};")
225-
conn.execute(f"GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO {role};")
226-
conn.execute(f"GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO {role};")
227-
228-
229-
_role_created: bool = False
230-
_role_privileges_created: MutableMapping[str, bool] = {}
231-
232-
233-
def create_model_role_guards(app_config: Any, using: str, **kwargs: Any):
234-
# Deprecated, will remove once getsentry is updated.
235-
global _role_created
236-
if "pytest" not in sys.argv[0] or not settings.USE_ROLE_SWAPPING_IN_TESTS:
237-
return
238-
239-
from sentry.db.models.fields.hybrid_cloud_foreign_key import HybridCloudForeignKey
240-
from sentry.models import (
241-
Organization,
242-
OrganizationMapping,
243-
OrganizationMember,
244-
OrganizationMemberMapping,
245-
)
246-
from sentry.testutils.silo import iter_models, reset_test_role, restrict_role
247-
248-
if not app_config or app_config.name != "sentry":
249-
return
250-
251-
with get_connection(using).cursor() as conn:
252-
conn.execute("SET ROLE 'postgres'")
253-
254-
if not _role_privileges_created.get(using, False):
255-
reset_test_role(role="postgres_unprivileged", using=using, create_role=not _role_created)
256-
_role_created = True
257-
_role_privileges_created[using] = True
258-
259-
# Protect Foreign Keys using hybrid cloud models from being deleted without using the privileged user.
260-
# Deletion should only occur when the developer is actively aware of the need to generate outboxes.
261-
seen_models: MutableSet[type] = set()
262-
for model in iter_models(app_config.name):
263-
for field in model._meta.fields:
264-
if not isinstance(field, HybridCloudForeignKey):
265-
continue
266-
fk_model = field.foreign_model
267-
if fk_model is None or fk_model in seen_models:
268-
continue
269-
seen_models.add(fk_model)
270-
271-
restrict_role(
272-
role="postgres_unprivileged", model=fk_model, revocation_type="DELETE", using=using
273-
)
274-
275-
# Protect organization members from being updated without also invoking the correct outbox logic.
276-
# If you hit test failures as a result of lacking these privileges, first ensure that you create the correct
277-
# outboxes in a transaction, and cover that transaction with `in_test_psql_role_override`
278-
restrict_role(role="postgres_unprivileged", model=OrganizationMember, revocation_type="INSERT")
279-
restrict_role(role="postgres_unprivileged", model=OrganizationMember, revocation_type="UPDATE")
280-
restrict_role(role="postgres_unprivileged", model=Organization, revocation_type="INSERT")
281-
restrict_role(role="postgres_unprivileged", model=Organization, revocation_type="UPDATE")
282-
restrict_role(role="postgres_unprivileged", model=OrganizationMapping, revocation_type="INSERT")
283-
restrict_role(role="postgres_unprivileged", model=OrganizationMapping, revocation_type="UPDATE")
284-
# OrganizationMember objects need to cascade, but they can't use the standard hybrid cloud foreign key because the
285-
# identifiers are not snowflake ids.
286-
restrict_role(role="postgres_unprivileged", model=OrganizationMember, revocation_type="DELETE")
287-
288-
restrict_role(
289-
role="postgres_unprivileged", model=OrganizationMemberMapping, revocation_type="INSERT"
290-
)
291-
292-
293-
# Listen to django's migration signal so that we're not trapped inside
294-
# test method transactions.
295-
post_migrate.connect(create_model_role_guards, dispatch_uid="create_model_role_guards", weak=False)
296-
297-
298-
def restrict_role(role: str, model: Any, revocation_type: str, using: str = "default") -> None:
299-
# Deprecated, will remove once getsentry is updated.
300-
if router.db_for_write(model) != using:
301-
return
302-
303-
using = router.db_for_write(model)
304-
with get_connection(using).cursor() as connection:
305-
connection.execute(f"REVOKE {revocation_type} ON public.{model._meta.db_table} FROM {role}")
306-
307-
308194
def protected_table(table: str, operation: str) -> re.Pattern:
309195
return re.compile(f'{operation}[^"]+"{table}"', re.IGNORECASE)
310196

0 commit comments

Comments
 (0)