mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-03 21:43:21 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			101 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
 | 
						|
from typing import Any, Dict, Optional, Text, Union, cast
 | 
						|
 | 
						|
from django.http import HttpRequest, HttpResponse
 | 
						|
from django.utils import timezone
 | 
						|
from django.utils.translation import ugettext as _
 | 
						|
 | 
						|
from zerver.lib.exceptions import JsonableError
 | 
						|
from zerver.lib.push_notifications import send_android_push_notification, \
 | 
						|
    send_apple_push_notification
 | 
						|
from zerver.lib.request import REQ, has_request_variables
 | 
						|
from zerver.lib.response import json_error, json_success
 | 
						|
from zerver.lib.validator import check_int
 | 
						|
from zerver.models import UserProfile
 | 
						|
from zerver.views.push_notifications import validate_token
 | 
						|
from zilencer.models import RemotePushDeviceToken, RemoteZulipServer
 | 
						|
 | 
						|
def validate_entity(entity):
 | 
						|
    # type: (Union[UserProfile, RemoteZulipServer]) -> None
 | 
						|
    if not isinstance(entity, RemoteZulipServer):
 | 
						|
        raise JsonableError(_("Must validate with valid Zulip server API key"))
 | 
						|
 | 
						|
def validate_bouncer_token_request(entity, token, kind):
 | 
						|
    # type: (Union[UserProfile, RemoteZulipServer], bytes, int) -> None
 | 
						|
    if kind not in [RemotePushDeviceToken.APNS, RemotePushDeviceToken.GCM]:
 | 
						|
        raise JsonableError(_("Invalid token type"))
 | 
						|
    validate_entity(entity)
 | 
						|
    validate_token(token, kind)
 | 
						|
 | 
						|
@has_request_variables
 | 
						|
def remote_server_register_push(request, entity, user_id=REQ(),
 | 
						|
                                token=REQ(), token_kind=REQ(validator=check_int), ios_app_id=None):
 | 
						|
    # type: (HttpRequest, Union[UserProfile, RemoteZulipServer], int, bytes, int, Optional[Text]) -> HttpResponse
 | 
						|
    validate_bouncer_token_request(entity, token, token_kind)
 | 
						|
    server = cast(RemoteZulipServer, entity)
 | 
						|
 | 
						|
    # If a user logged out on a device and failed to unregister,
 | 
						|
    # we should delete any other user associations for this token
 | 
						|
    # & RemoteServer pair
 | 
						|
    RemotePushDeviceToken.objects.filter(
 | 
						|
        token=token, kind=token_kind, server=server).exclude(user_id=user_id).delete()
 | 
						|
 | 
						|
    # Save or update
 | 
						|
    remote_token, created = RemotePushDeviceToken.objects.update_or_create(
 | 
						|
        user_id=user_id,
 | 
						|
        server=server,
 | 
						|
        kind=token_kind,
 | 
						|
        token=token,
 | 
						|
        defaults=dict(
 | 
						|
            ios_app_id=ios_app_id,
 | 
						|
            last_updated=timezone.now()))
 | 
						|
 | 
						|
    return json_success()
 | 
						|
 | 
						|
@has_request_variables
 | 
						|
def remote_server_unregister_push(request, entity, token=REQ(),
 | 
						|
                                  token_kind=REQ(validator=check_int), ios_app_id=None):
 | 
						|
    # type: (HttpRequest, Union[UserProfile, RemoteZulipServer], bytes, int, Optional[Text]) -> HttpResponse
 | 
						|
    validate_bouncer_token_request(entity, token, token_kind)
 | 
						|
    server = cast(RemoteZulipServer, entity)
 | 
						|
    deleted = RemotePushDeviceToken.objects.filter(token=token,
 | 
						|
                                                   kind=token_kind,
 | 
						|
                                                   server=server).delete()
 | 
						|
    if deleted[0] == 0:
 | 
						|
        return json_error(_("Token does not exist"))
 | 
						|
 | 
						|
    return json_success()
 | 
						|
 | 
						|
@has_request_variables
 | 
						|
def remote_server_notify_push(request,  # type: HttpRequest
 | 
						|
                              entity,  # type: Union[UserProfile, RemoteZulipServer]
 | 
						|
                              payload=REQ(argument_type='body')  # type: Dict[str, Any]
 | 
						|
                              ):
 | 
						|
    # type: (...) -> HttpResponse
 | 
						|
    validate_entity(entity)
 | 
						|
    server = cast(RemoteZulipServer, entity)
 | 
						|
 | 
						|
    user_id = payload['user_id']
 | 
						|
    gcm_payload = payload['gcm_payload']
 | 
						|
    apns_payload = payload['apns_payload']
 | 
						|
 | 
						|
    android_devices = list(RemotePushDeviceToken.objects.filter(
 | 
						|
        user_id=user_id,
 | 
						|
        kind=RemotePushDeviceToken.GCM,
 | 
						|
        server=server
 | 
						|
    ))
 | 
						|
 | 
						|
    apple_devices = list(RemotePushDeviceToken.objects.filter(
 | 
						|
        user_id=user_id,
 | 
						|
        kind=RemotePushDeviceToken.APNS,
 | 
						|
        server=server
 | 
						|
    ))
 | 
						|
 | 
						|
    if android_devices:
 | 
						|
        send_android_push_notification(android_devices, gcm_payload, remote=True)
 | 
						|
 | 
						|
    if apple_devices:
 | 
						|
        send_apple_push_notification(user_id, apple_devices, apns_payload)
 | 
						|
 | 
						|
    return json_success()
 |