remove apns + fix django-push-notifications migrations (#984)

- removes APNS support
- changes the `django-push-notification` library from the `iskhakov`
fork to the [`grafana`
fork](https://github.com/grafana/django-push-notifications). This new
fork basically just patches an issue which affected the database
migrations of this django app (previously the library would not respect
the `USER_MODEL` setting when creating its tables and would instead
reference the `auth_user` table.. which we don't want)
- add `--no-cache` flag to the `make build` command

**NOTE**
A migration should be applied as follows:
```bash
# remove the four push_notifications tables, which have improper foreign key references
python manage.py migrate push_notifications zero

# recreate the tables with the proper foreign key references
python manage.py migrate
```
This commit is contained in:
Joey Orlando 2022-12-13 13:00:59 +01:00 committed by GitHub
parent d2d73093a8
commit 5967d5af63
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 18 additions and 107 deletions

View file

@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## v1.1.8 (TBD)
### Changed
- removed APNS support
- changed the `django-push-notification` library from the `iskhakov` fork to the [`grafana` fork](https://github.com/grafana/django-push-notifications).
This new fork basically patches an issue which affected the database migrations of this django app (previously the
library would not respect the `USER_MODEL` setting when creating its tables and would instead reference the
`auth_user` table.. which we don't want)
- add `--no-cache` flag to the `make build` command
## v1.1.7 (2022-12-09)
### Fixed

View file

@ -86,7 +86,7 @@ restart:
$(call run_docker_compose_command,restart)
build:
$(call run_docker_compose_command,build)
$(call run_docker_compose_command,build --no-cache)
cleanup: stop
docker system prune --filter label="$(DOCKER_COMPOSE_DEV_LABEL)" --all --volumes

View file

@ -1,7 +1,5 @@
from django.conf import settings
from django.urls import include, path, re_path
from apps.mobile_app.views import APNSDeviceAuthorizedViewSet
from common.api_helpers.optional_slash_router import OptionalSlashRouter, optional_slash_path
from .views import UserNotificationPolicyView, auth
@ -68,10 +66,6 @@ router.register(r"tokens", PublicApiTokenView, basename="api_token")
router.register(r"live_settings", LiveSettingViewSet, basename="live_settings")
router.register(r"oncall_shifts", OnCallShiftView, basename="oncall_shifts")
# TODO: remove this when the hackathon app is deprecated (APNSDeviceAuthorizedViewSet is registered in mobile_app)
if settings.FEATURE_MOBILE_APP_INTEGRATION_ENABLED:
router.register(r"device/apns", APNSDeviceAuthorizedViewSet)
urlpatterns = [
path("", include(router.urls)),
optional_slash_path("user", CurrentUserView.as_view(), name="api-user"),

View file

@ -28,8 +28,7 @@ from apps.auth_token.constants import SCHEDULE_EXPORT_TOKEN_NAME
from apps.auth_token.models import UserScheduleExportAuthToken
from apps.base.messaging import get_messaging_backend_from_id
from apps.base.utils import live_settings
from apps.mobile_app.auth import MobileAppAuthTokenAuthentication, MobileAppVerificationTokenAuthentication
from apps.mobile_app.models import MobileAppAuthToken
from apps.mobile_app.auth import MobileAppAuthTokenAuthentication
from apps.telegram.client import TelegramClient
from apps.telegram.models import TelegramVerificationCode
from apps.twilioapp.phone_manager import PhoneManager
@ -128,7 +127,6 @@ class UserView(
"unlink_backend": [RBACPermission.Permissions.USER_SETTINGS_WRITE],
"make_test_call": [RBACPermission.Permissions.USER_SETTINGS_WRITE],
"export_token": [RBACPermission.Permissions.USER_SETTINGS_WRITE],
"mobile_app_auth_token": [RBACPermission.Permissions.USER_SETTINGS_WRITE],
}
rbac_object_permissions = {
@ -149,7 +147,6 @@ class UserView(
"unlink_backend",
"make_test_call",
"export_token",
"mobile_app_auth_token",
],
}
@ -471,64 +468,3 @@ class UserView(
except UserScheduleExportAuthToken.DoesNotExist:
raise NotFound
return Response(status=status.HTTP_204_NO_CONTENT)
@action(
methods=["get", "post", "delete"],
detail=False,
authentication_classes=(MobileAppVerificationTokenAuthentication,),
)
def mobile_app_auth_token(self, request):
"""
TODO: remove after hackathon app is deprecated (see apps.mobile_app.views.MobileAppAuthTokenAPIView)
"""
DynamicSetting = apps.get_model("base", "DynamicSetting")
if not settings.FEATURE_MOBILE_APP_INTEGRATION_ENABLED:
return Response(status=status.HTTP_404_NOT_FOUND)
mobile_app_settings = DynamicSetting.objects.get_or_create(
name="mobile_app_settings",
defaults={
"json_value": {
"org_ids": [],
}
},
)[0]
if self.request.auth.organization.pk not in mobile_app_settings.json_value["org_ids"]:
return Response(status=status.HTTP_404_NOT_FOUND)
if self.request.method == "GET":
try:
token = MobileAppAuthToken.objects.get(user=self.request.user)
except MobileAppAuthToken.DoesNotExist:
raise NotFound
response = {
"token_id": token.id,
"user_id": token.user_id,
"organization_id": token.organization_id,
"created_at": token.created_at,
"revoked_at": token.revoked_at,
}
return Response(response, status=status.HTTP_200_OK)
if self.request.method == "POST":
# If token already exists revoke it
try:
token = MobileAppAuthToken.objects.get(user=self.request.user)
token.delete()
except MobileAppAuthToken.DoesNotExist:
pass
instance, token = MobileAppAuthToken.create_auth_token(self.request.user, self.request.user.organization)
data = {"id": instance.pk, "token": token, "created_at": instance.created_at}
return Response(data, status=status.HTTP_201_CREATED)
if self.request.method == "DELETE":
try:
token = MobileAppAuthToken.objects.get(user=self.request.user)
token.delete()
except MobileAppAuthToken.DoesNotExist:
raise NotFound
return Response(status=status.HTTP_204_NO_CONTENT)

View file

@ -1,7 +1,7 @@
import json
from django.conf import settings
from push_notifications.models import APNSDevice, GCMDevice
from push_notifications.models import GCMDevice
from apps.base.messaging import BaseMessagingBackend
from apps.mobile_app.tasks import notify_user_async
@ -35,7 +35,6 @@ class MobileAppBackend(BaseMessagingBackend):
token.delete()
# delete push notification related info for user
APNSDevice.objects.filter(user=user).delete()
GCMDevice.objects.filter(user=user).delete()
def serialize_user(self, user):

View file

@ -1,6 +1,6 @@
from celery.utils.log import get_task_logger
from django.conf import settings
from push_notifications.models import APNSDevice, GCMDevice
from push_notifications.models import GCMDevice
from apps.alerts.models import AlertGroup
from apps.mobile_app.alert_rendering import get_push_notification_message
@ -34,12 +34,10 @@ def notify_user_async(user_pk, alert_group_pk, notification_policy_pk, critical)
logger.warning(f"User notification policy {notification_policy_pk} does not exist")
return
# APNS is for notifying iOS devices, GCM for Android
apns_devices_to_notify = APNSDevice.objects.filter(user=user)
gcm_devices_to_notify = GCMDevice.objects.filter(user=user)
# create an error log in case user has no devices set up
if not apns_devices_to_notify.exists() and not gcm_devices_to_notify.exists():
if not gcm_devices_to_notify.exists():
UserNotificationPolicyLogRecord.objects.create(
author=user,
type=UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_FAILED,
@ -67,20 +65,6 @@ def notify_user_async(user_pk, alert_group_pk, notification_policy_pk, critical)
"sound": "bingbong.aiff",
}
apns_devices_to_notify.send_message(
message,
thread_id=thread_id,
category="USER_NEW_INCIDENT", # TODO: rename to USER_NEW_ALERT_GROUP
extra={
"orgId": alert_group.channel.organization.public_primary_key,
"orgName": alert_group.channel.organization.stack_slug,
"alertGroupId": alert_group.public_primary_key,
"incidentId": alert_group.public_primary_key, # TODO: remove after hackathon app is deprecated
"status": alert_group.status,
"aps": aps,
},
)
gcm_devices_to_notify.send_message(
message,
thread_id=thread_id,

View file

@ -1,13 +1,12 @@
from django.conf import settings
from apps.mobile_app.fcm_relay import FCMRelayView
from apps.mobile_app.views import APNSDeviceAuthorizedViewSet, FCMDeviceAuthorizedViewSet, MobileAppAuthTokenAPIView
from apps.mobile_app.views import FCMDeviceAuthorizedViewSet, MobileAppAuthTokenAPIView
from common.api_helpers.optional_slash_router import OptionalSlashRouter, optional_slash_path
app_name = "mobile_app"
router = OptionalSlashRouter()
router.register("apns", APNSDeviceAuthorizedViewSet, basename="apns")
router.register("fcm", FCMDeviceAuthorizedViewSet, basename="fcm")
urlpatterns = [

View file

@ -1,4 +1,3 @@
from push_notifications.api.rest_framework import APNSDeviceAuthorizedViewSet as BaseAPNSDeviceAuthorizedViewSet
from push_notifications.api.rest_framework import GCMDeviceAuthorizedViewSet, GCMDeviceSerializer
from rest_framework import status
from rest_framework.exceptions import NotFound
@ -10,10 +9,6 @@ from apps.mobile_app.auth import MobileAppAuthTokenAuthentication, MobileAppVeri
from apps.mobile_app.models import MobileAppAuthToken
class APNSDeviceAuthorizedViewSet(BaseAPNSDeviceAuthorizedViewSet):
authentication_classes = (MobileAppAuthTokenAuthentication,)
class FCMDeviceAuthorizedViewSet(GCMDeviceAuthorizedViewSet):
class FCMDeviceSerializer(GCMDeviceSerializer):
"""

View file

@ -33,12 +33,11 @@ django-log-request-id==1.6.0
django-polymorphic==3.0.0
django-rest-polymorphic==0.1.9
pre-commit==2.15.0
https://github.com/iskhakov/django-push-notifications/archive/refs/tags/3.0.0-fix-migration.tar.gz
https://github.com/grafana/django-push-notifications/archive/refs/tags/3.0.0-fix-migration.tar.gz
django-mirage-field==1.3.0
django-mysql==4.6.0
PyMySQL==1.0.2
psycopg2-binary==2.9.3
emoji==1.7.0
apns2==0.7.2
regex==2021.11.2
psutil==5.9.4

View file

@ -556,12 +556,6 @@ PUSH_NOTIFICATIONS_SETTINGS = {
"FCM_POST_URL": os.getenv("FCM_POST_URL", default="https://fcm.googleapis.com/fcm/send"),
"USER_MODEL": "user_management.User",
"UPDATE_ON_DUPLICATE_REG_ID": True,
# TODO: remove APNS related endpoints after the hackathon app is deprecated
"APNS_AUTH_KEY_PATH": os.environ.get("APNS_AUTH_KEY_PATH", None),
"APNS_TOPIC": os.environ.get("APNS_TOPIC", None),
"APNS_AUTH_KEY_ID": os.environ.get("APNS_AUTH_KEY_ID", None),
"APNS_TEAM_ID": os.environ.get("APNS_TEAM_ID", None),
"APNS_USE_SANDBOX": getenv_boolean("APNS_USE_SANDBOX", True),
}
FCM_RELAY_ENABLED = getenv_boolean("FCM_RELAY_ENABLED", default=False)