Skip to content

Commit 75e8cb5

Browse files
iamrajjoshiandrewshie-sentry
authored andcommitted
🔧 chore(data-secrecy v2): remove data secrecy v1 RPC Service (#95338)
1 parent 0df341c commit 75e8cb5

File tree

14 files changed

+71
-236
lines changed

14 files changed

+71
-236
lines changed

src/sentry/data_secrecy/data_access_grant_service/__init__.py

Whitespace-only changes.

src/sentry/data_secrecy/data_access_grant_service/impl.py

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

src/sentry/data_secrecy/data_access_grant_service/model.py

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

src/sentry/data_secrecy/data_access_grant_service/serial.py

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

src/sentry/data_secrecy/data_access_grant_service/service.py

Lines changed: 0 additions & 31 deletions
This file was deleted.
Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
from django.conf import settings
2-
from django.utils import timezone
32

43
from sentry import features
5-
from sentry.data_secrecy.service.service import data_secrecy_service
64
from sentry.models.organization import Organization
75
from sentry.organizations.services.organization import RpcOrganization, RpcUserOrganizationContext
86

@@ -11,7 +9,7 @@ def should_allow_superuser_access(
119
organization_context: Organization | RpcUserOrganizationContext,
1210
) -> bool:
1311

14-
# If self hosted installation, superuser access is allowed
12+
# If self hosted installation, allow superuser access
1513
if settings.SENTRY_SELF_HOSTED:
1614
return True
1715

@@ -21,19 +19,13 @@ def should_allow_superuser_access(
2119
else:
2220
organization = organization_context
2321

24-
# If organization does not have data-secrecy feature, return True
22+
# If organization does not have data-secrecy feature, allow superuser access
2523
if not features.has("organizations:data-secrecy", organization):
2624
return True
2725

28-
# If organization's prevent_superuser_access bitflag is False, return True
26+
# If organization's prevent_superuser_access bitflag is False, allow superuser access
2927
if not organization.flags.prevent_superuser_access:
3028
return True
3129

32-
ds = data_secrecy_service.get_data_secrecy_waiver(organization_id=organization.id)
33-
34-
# If no data secrecy waiver exists, data secrecy is active
35-
if ds is None:
36-
return False
37-
38-
# If current time is before the access_end time of the waiver, data secrecy is active
39-
return timezone.now() <= ds.access_end
30+
# If organization has data-secrecy feature, but prevent_superuser_access is True, prevent superuser access
31+
return False
Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,35 @@
1-
from sentry.data_secrecy.models.datasecrecywaiver import DataSecrecyWaiver
2-
from sentry.data_secrecy.service.model import RpcDataSecrecyWaiver
3-
from sentry.data_secrecy.service.serial import serialize_data_secrecy_waiver
4-
from sentry.data_secrecy.service.service import DataSecrecyService
1+
from django.db import models
2+
from django.utils import timezone
53

4+
from sentry.data_secrecy.models.data_access_grant import DataAccessGrant
5+
from sentry.data_secrecy.service.model import RpcEffectiveGrantStatus
6+
from sentry.data_secrecy.service.serial import serialize_effective_grant_status
7+
from sentry.data_secrecy.service.service import DataAccessGrantService
68

7-
class DatabaseBackedDataSecrecyService(DataSecrecyService):
8-
def get_data_secrecy_waiver(self, *, organization_id: int) -> RpcDataSecrecyWaiver | None:
9-
try:
10-
data_secrecy_waiver = DataSecrecyWaiver.objects.filter(
11-
organization_id=organization_id
12-
).get()
13-
except DataSecrecyWaiver.DoesNotExist:
9+
10+
class DatabaseBackedDataAccessGrantService(DataAccessGrantService):
11+
def get_effective_grant_status(self, *, organization_id: int) -> RpcEffectiveGrantStatus | None:
12+
"""
13+
Get the effective grant status for an organization.
14+
"""
15+
now = timezone.now()
16+
active_grants = DataAccessGrant.objects.filter(
17+
organization_id=organization_id,
18+
grant_start__lte=now,
19+
grant_end__gt=now,
20+
revocation_date__isnull=True, # Not revoked
21+
)
22+
23+
if not active_grants.exists():
1424
return None
1525

16-
return serialize_data_secrecy_waiver(data_secrecy_waiver=data_secrecy_waiver)
26+
# Calculate aggregate grant status - only need the time window for access control
27+
min_start = active_grants.aggregate(min_start=models.Min("grant_start"))["min_start"]
28+
max_end = active_grants.aggregate(max_end=models.Max("grant_end"))["max_end"]
29+
30+
grant_status = {
31+
"access_start": min_start.isoformat(),
32+
"access_end": max_end.isoformat(),
33+
}
34+
35+
return serialize_effective_grant_status(grant_status, organization_id)
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
from datetime import datetime
22

3-
from django.utils import timezone
4-
from pydantic import Field
5-
63
from sentry.hybridcloud.rpc import RpcModel
74

85

9-
class RpcDataSecrecyWaiver(RpcModel):
10-
organization_id: int = -1
11-
access_start: datetime = Field(default_factory=timezone.now)
12-
access_end: datetime = Field(default_factory=timezone.now)
13-
zendesk_tickets: list[str] = Field(default_factory=list)
6+
class RpcEffectiveGrantStatus(RpcModel):
7+
"""
8+
Simplified model for access control - only contains essential, aggregated grant information.
9+
"""
10+
11+
organization_id: int
12+
access_start: datetime
13+
access_end: datetime
Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
1-
from sentry.data_secrecy.models.datasecrecywaiver import DataSecrecyWaiver
2-
from sentry.data_secrecy.service.model import RpcDataSecrecyWaiver
1+
from datetime import datetime
2+
from typing import Any
33

4+
from sentry.data_secrecy.service.model import RpcEffectiveGrantStatus
45

5-
def serialize_data_secrecy_waiver(data_secrecy_waiver: DataSecrecyWaiver) -> RpcDataSecrecyWaiver:
6-
return RpcDataSecrecyWaiver(
7-
organization_id=data_secrecy_waiver.organization.id,
8-
access_start=data_secrecy_waiver.access_start,
9-
access_end=data_secrecy_waiver.access_end,
10-
zendesk_tickets=data_secrecy_waiver.zendesk_tickets,
6+
7+
def serialize_effective_grant_status(
8+
grant_status: dict[str, Any], organization_id: int
9+
) -> RpcEffectiveGrantStatus:
10+
"""
11+
Convert cached grant status to simplified RpcGrantStatus model for access control.
12+
"""
13+
14+
return RpcEffectiveGrantStatus(
15+
organization_id=organization_id,
16+
access_start=datetime.fromisoformat(grant_status["access_start"]),
17+
access_end=datetime.fromisoformat(grant_status["access_end"]),
1118
)

src/sentry/data_secrecy/service/service.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,25 @@
55

66
import abc
77

8-
from sentry.data_secrecy.service.model import RpcDataSecrecyWaiver
9-
from sentry.hybridcloud.rpc.resolvers import ByOrganizationId
10-
from sentry.hybridcloud.rpc.service import RpcService, regional_rpc_method
8+
from sentry.data_secrecy.service.model import RpcEffectiveGrantStatus
9+
from sentry.hybridcloud.rpc.service import RpcService, rpc_method
1110
from sentry.silo.base import SiloMode
1211

1312

14-
class DataSecrecyService(RpcService):
15-
key = "data_secrecy"
16-
local_mode = SiloMode.REGION
13+
class DataAccessGrantService(RpcService):
14+
key = "data_access_grant"
15+
local_mode = SiloMode.CONTROL
1716

1817
@classmethod
1918
def get_local_implementation(cls) -> RpcService:
20-
from sentry.data_secrecy.service.impl import DatabaseBackedDataSecrecyService
19+
from sentry.data_secrecy.service.impl import DatabaseBackedDataAccessGrantService
2120

22-
return DatabaseBackedDataSecrecyService()
21+
return DatabaseBackedDataAccessGrantService()
2322

24-
@regional_rpc_method(resolve=ByOrganizationId())
23+
@rpc_method
2524
@abc.abstractmethod
26-
def get_data_secrecy_waiver(self, *, organization_id: int) -> RpcDataSecrecyWaiver | None:
25+
def get_effective_grant_status(self, *, organization_id: int) -> RpcEffectiveGrantStatus | None:
2726
pass
2827

2928

30-
data_secrecy_service = DataSecrecyService.create_delegation()
29+
data_access_grant_service = DataAccessGrantService.create_delegation()

0 commit comments

Comments
 (0)