Skip to content

Commit

Permalink
Adds support for large iOS device tokens
Browse files Browse the repository at this point in the history
- Changed max_length for registration_id to 200 from 64
- Added tests for 100 bytes device tokens
- Changed Validation condition check in APNSDeviceSerializer
- Changes to comments and readme
- Added migrations
  • Loading branch information
ulhas committed Jan 6, 2016
1 parent 6988afd commit b83993c
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 7 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ ViewSets are available for both APNS and GCM devices in two permission flavors:
- Permissions are ``IsAuthenticated`` and custom permission ``IsOwner``, which will only allow the ``request.user`` to get and update devices that belong to that user
- Requires a user to be authenticated, so all devices will be associated with a user

When creating an ``APNSDevice``, the ``registration_id`` is validated to be a 64-character hexadecimal string.
When creating an ``APNSDevice``, the ``registration_id`` is validated to be a 64-character or 200-character hexadecimal string. Since 2016, device tokens are to be increased from 32 bytes to 100 bytes.

Routes can be added one of two ways:

Expand Down
5 changes: 3 additions & 2 deletions push_notifications/api/rest_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,10 @@ class Meta(DeviceSerializerMixin.Meta):
model = APNSDevice

def validate_registration_id(self, value):
# iOS device tokens are 256-bit hexadecimal (64 characters)
# iOS device tokens are 256-bit hexadecimal (64 characters). In 2016 Apple is increasing
# iOS device tokens to 100 bytes hexadecimal (200 characters).

if hex_re.match(value) is None or len(value) != 64:
if hex_re.match(value) is None or len(value) not in (64, 200):
raise ValidationError("Registration ID (device token) is invalid")

return value
Expand Down
20 changes: 20 additions & 0 deletions push_notifications/migrations/0002_auto_20160106_0850.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.1 on 2016-01-06 08:50
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('push_notifications', '0001_initial'),
]

operations = [
migrations.AlterField(
model_name='apnsdevice',
name='registration_id',
field=models.CharField(max_length=200, unique=True, verbose_name='Registration ID'),
),
]
2 changes: 1 addition & 1 deletion push_notifications/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def send_message(self, message, **kwargs):
class APNSDevice(Device):
device_id = models.UUIDField(verbose_name=_("Device ID"), blank=True, null=True, db_index=True,
help_text="UDID / UIDevice.identifierForVendor()")
registration_id = models.CharField(verbose_name=_("Registration ID"), max_length=64, unique=True)
registration_id = models.CharField(verbose_name=_("Registration ID"), max_length=200, unique=True)

objects = APNSDeviceManager()

Expand Down
21 changes: 18 additions & 3 deletions tests/test_rest_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,38 @@

class APNSDeviceSerializerTestCase(TestCase):
def test_validation(self):
# valid data - upper case
# valid data - 32 bytes upper case
serializer = APNSDeviceSerializer(data={
"registration_id": "AEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAE",
"name": "Apple iPhone 6+",
"device_id": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
})
self.assertTrue(serializer.is_valid())

# valid data - lower case
# valid data - 32 bytes lower case
serializer = APNSDeviceSerializer(data={
"registration_id": "aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae",
"name": "Apple iPhone 6+",
"device_id": "ffffffffffffffffffffffffffffffff",
})
self.assertTrue(serializer.is_valid())

# valid data - 100 bytes upper case
serializer = APNSDeviceSerializer(data={
"registration_id": "AEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAE",
"name": "Apple iPhone 6+",
"device_id": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
})
self.assertTrue(serializer.is_valid())

# valid data - 100 bytes lower case
serializer = APNSDeviceSerializer(data={
"registration_id": "aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae",
"name": "Apple iPhone 6+",
"device_id": "ffffffffffffffffffffffffffffffff",
})
self.assertTrue(serializer.is_valid())

# invalid data - device_id, registration_id
serializer = APNSDeviceSerializer(data={
"registration_id": "invalid device token contains no hex",
Expand Down Expand Up @@ -102,4 +118,3 @@ def test_device_id_validation_value_between_signed_unsigned_64b_int_maximums(sel
"device_id": "e87a4e72d634997c",
})
self.assertTrue(serializer.is_valid())

0 comments on commit b83993c

Please sign in to comment.