Skip to content

Commit a0fb4ce

Browse files
ceorourkeconstantinius
authored andcommitted
feat(sentry apps): Add HC methods to fetch sentry apps for an org and update a sentry app (#98080)
Add a method to `app_service` to fetch all active (not pending deletion) sentry apps for an organization and a method to update a sentry app. Used for getsentry/getsentry#18204
1 parent e52e00f commit a0fb4ce

File tree

4 files changed

+86
-1
lines changed

4 files changed

+86
-1
lines changed

src/sentry/sentry_apps/services/app/impl.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
RpcSentryAppService,
3434
SentryAppInstallationFilterArgs,
3535
)
36+
from sentry.sentry_apps.services.app.model import SentryAppUpdateArgs
3637
from sentry.sentry_apps.services.app.serial import (
3738
serialize_sentry_app,
3839
serialize_sentry_app_component,
@@ -333,6 +334,33 @@ def get_published_sentry_apps_for_organization(
333334
)
334335
return [serialize_sentry_app(app) for app in published_apps]
335336

337+
def get_sentry_apps_for_organization(self, *, organization_id: int) -> list[RpcSentryApp]:
338+
"""
339+
Get active Sentry Apps for a given organization
340+
"""
341+
sentry_apps = SentryApp.objects.filter(
342+
owner_id=organization_id, application__isnull=False
343+
).exclude(status=SentryAppStatus.DELETION_IN_PROGRESS)
344+
return [serialize_sentry_app(app) for app in sentry_apps]
345+
346+
def update_sentry_app(
347+
self,
348+
*,
349+
id: int,
350+
attrs: SentryAppUpdateArgs,
351+
) -> RpcSentryApp | None:
352+
try:
353+
sentry_app = SentryApp.objects.get(id=id)
354+
except SentryApp.DoesNotExist:
355+
return None
356+
357+
if len(attrs):
358+
for k, v in attrs.items():
359+
setattr(sentry_app, k, v)
360+
sentry_app.save()
361+
362+
return serialize_sentry_app(sentry_app)
363+
336364
def get_internal_integrations(
337365
self, *, organization_id: int, integration_name: str
338366
) -> list[RpcSentryApp]:

src/sentry/sentry_apps/services/app/model.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,3 +196,9 @@ class SentryAppInstallationFilterArgs(TypedDict, total=False):
196196
status: int
197197
api_token_id: int
198198
api_installation_token_id: str
199+
200+
201+
class SentryAppUpdateArgs(TypedDict, total=False):
202+
events: list[str]
203+
name: str
204+
# TODO add whatever else as needed

src/sentry/sentry_apps/services/app/service.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
RpcSentryAppService,
2121
SentryAppInstallationFilterArgs,
2222
)
23-
from sentry.sentry_apps.services.app.model import RpcSentryAppComponentContext
23+
from sentry.sentry_apps.services.app.model import RpcSentryAppComponentContext, SentryAppUpdateArgs
2424
from sentry.silo.base import SiloMode
2525
from sentry.users.services.user import RpcUser
2626

@@ -192,6 +192,16 @@ def get_published_sentry_apps_for_organization(
192192
) -> list[RpcSentryApp]:
193193
pass
194194

195+
@rpc_method
196+
@abc.abstractmethod
197+
def get_sentry_apps_for_organization(self, *, organization_id: int) -> list[RpcSentryApp]:
198+
pass
199+
200+
@rpc_method
201+
@abc.abstractmethod
202+
def update_sentry_app(self, *, id: int, attrs: SentryAppUpdateArgs) -> RpcSentryApp | None:
203+
pass
204+
195205
@rpc_method
196206
@abc.abstractmethod
197207
def get_internal_integrations(

tests/sentry/sentry_apps/services/test_app.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,47 @@ def test_get_installation_org_id_by_token_id() -> None:
238238
assert result is None
239239

240240

241+
@django_db_all(transaction=True)
242+
@all_silo_test
243+
def test_get_sentry_apps_for_organization() -> None:
244+
org = Factories.create_organization()
245+
other_org = Factories.create_organization()
246+
247+
# Create internal integrations
248+
Factories.create_internal_integration(
249+
name="Test Integration",
250+
organization_id=org.id,
251+
)
252+
Factories.create_internal_integration(
253+
name="Test Integration",
254+
organization_id=other_org.id,
255+
)
256+
result = app_service.get_sentry_apps_for_organization(organization_id=org.id)
257+
assert len(result) == 1
258+
assert result[0].owner_id == org.id
259+
260+
261+
@django_db_all(transaction=True)
262+
@all_silo_test
263+
def test_update_sentry_app() -> None:
264+
org = Factories.create_organization()
265+
266+
sentry_app = Factories.create_internal_integration(
267+
name="Test Integration",
268+
organization_id=org.id,
269+
events=[
270+
"issue.resolved",
271+
"issue.unresolved",
272+
"issue.ignored",
273+
"issue.assigned",
274+
"error.created",
275+
],
276+
)
277+
result = app_service.update_sentry_app(id=sentry_app.id, attrs=dict(events=["error.created"]))
278+
assert result
279+
assert result.events == ["error.created"]
280+
281+
241282
@django_db_all(transaction=True)
242283
@all_silo_test
243284
def test_get_internal_integrations() -> None:

0 commit comments

Comments
 (0)